From 61b5fa0beb2f6ead1a520e9404bc1f5660dfb1cd Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Tue, 12 May 2015 11:22:06 +0200 Subject: [PATCH] Validation PSR-2 : Tabs to spaces --- Classes/PHPExcel/Calculation.php | 7252 ++++++++--------- Classes/PHPExcel/DocumentSecurity.php | 24 +- Classes/PHPExcel/Helper/HTML.php | 18 +- Classes/PHPExcel/Reader/Excel2007/Chart.php | 888 +- 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 | 606 +- Classes/PHPExcel/Shared/Drawing.php | 262 +- Classes/PHPExcel/Shared/Escher.php | 98 +- .../PHPExcel/Shared/Escher/DgContainer.php | 76 +- .../Escher/DgContainer/SpgrContainer.php | 130 +- .../DgContainer/SpgrContainer/SpContainer.php | 640 +- .../PHPExcel/Shared/Escher/DggContainer.php | 300 +- .../Escher/DggContainer/BstoreContainer.php | 52 +- .../DggContainer/BstoreContainer/BSE.php | 150 +- .../DggContainer/BstoreContainer/BSE/Blip.php | 98 +- Classes/PHPExcel/Shared/Excel5.php | 476 +- Classes/PHPExcel/Shared/File.php | 248 +- Classes/PHPExcel/Shared/Font.php | 1250 +-- .../Shared/JAMA/CholeskyDecomposition.php | 248 +- .../Shared/JAMA/EigenvalueDecomposition.php | 1624 ++-- .../PHPExcel/Shared/JAMA/LUDecomposition.php | 454 +- Classes/PHPExcel/Shared/JAMA/Matrix.php | 2082 ++--- .../PHPExcel/Shared/JAMA/QRDecomposition.php | 418 +- .../JAMA/SingularValueDecomposition.php | 968 +-- Classes/PHPExcel/Shared/JAMA/utils/Error.php | 32 +- Classes/PHPExcel/Shared/JAMA/utils/Maths.php | 58 +- Classes/PHPExcel/Shared/OLE.php | 886 +- .../Shared/OLE/ChainedBlockStream.php | 332 +- Classes/PHPExcel/Shared/OLE/PPS.php | 360 +- Classes/PHPExcel/Shared/OLE/PPS/File.php | 100 +- Classes/PHPExcel/Shared/OLE/PPS/Root.php | 814 +- Classes/PHPExcel/Shared/OLERead.php | 444 +- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 318 +- Classes/PHPExcel/Shared/PasswordHasher.php | 38 +- Classes/PHPExcel/Shared/String.php | 1382 ++-- Classes/PHPExcel/Shared/TimeZone.php | 187 +- Classes/PHPExcel/Shared/XMLWriter.php | 154 +- Classes/PHPExcel/Shared/ZipArchive.php | 111 +- Classes/PHPExcel/Shared/ZipStreamWrapper.php | 82 +- .../PHPExcel/Shared/trend/bestFitClass.php | 782 +- .../Shared/trend/exponentialBestFitClass.php | 184 +- .../Shared/trend/linearBestFitClass.php | 120 +- .../Shared/trend/logarithmicBestFitClass.php | 136 +- .../Shared/trend/polynomialBestFitClass.php | 324 +- .../Shared/trend/powerBestFitClass.php | 176 +- Classes/PHPExcel/Shared/trend/trendClass.php | 212 +- Classes/PHPExcel/Worksheet/AutoFilter.php | 1492 ++-- .../PHPExcel/Worksheet/AutoFilter/Column.php | 630 +- .../Worksheet/AutoFilter/Column/Rule.php | 782 +- Classes/PHPExcel/Worksheet/BaseDrawing.php | 436 +- .../PHPExcel/Worksheet/ColumnDimension.php | 2 +- Classes/PHPExcel/Worksheet/Drawing.php | 118 +- Classes/PHPExcel/Worksheet/Drawing/Shadow.php | 232 +- Classes/PHPExcel/Worksheet/HeaderFooter.php | 278 +- .../Worksheet/HeaderFooterDrawing.php | 292 +- Classes/PHPExcel/Worksheet/MemoryDrawing.php | 174 +- Classes/PHPExcel/Worksheet/PageMargins.php | 136 +- Classes/PHPExcel/Worksheet/PageSetup.php | 1152 +-- Classes/PHPExcel/Worksheet/Protection.php | 376 +- Classes/PHPExcel/Worksheet/SheetView.php | 262 +- .../PHPExcel/Writer/Excel2007/WriterPart.php | 2 +- .../Writer/OpenDocument/Cell/Comment.php | 2 +- .../PHPExcel/Writer/OpenDocument/Content.php | 2 +- composer.json | 2 +- 67 files changed, 16708 insertions(+), 16712 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 6f0f3a8..34db773 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 */ + /** 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'; + /** 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; + private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE; - /** - * Instance of this class - * - * @access private - * @var PHPExcel_Calculation - */ - private static $_instance; + /** + * 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 - */ + /** + * 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 + * + * @access private + * @var array + */ + private $_calculationCache = array (); - /** - * Calculation cache enabled - * - * @access private - * @var boolean - */ - private $_calculationCacheEnabled = TRUE; + /** + * 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 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 - ); + /** + * 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; + /** + * 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; + /** + * 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; + /** + * 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; + /** + * 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(); + 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; + /** + * 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 = ''; + private $_cyclicFormulaCell = ''; - /** - * Number of iterations for cyclic formulae - * - * @var integer - * - */ - public $cyclicFormulaCount = 1; + /** + * Number of iterations for cyclic formulae + * + * @var integer + * + */ + public $cyclicFormulaCount = 1; - /** - * Precision used for calculations - * - * @var integer - * - */ - private $_savedPrecision = 14; + /** + * Precision used for calculations + * + * @var integer + * + */ + private $_savedPrecision = 14; - /** - * The current locale setting - * - * @var string - * - */ - private static $_localeLanguage = 'en_us'; // US English (default locale) + /** + * 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(); + /** + * 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' - ); + /** + * 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 - ); + /** + * 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' - ) - ); + // 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' - ) - ); + // 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); + 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; - } + 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() + $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()]); - } - } + public function __destruct() { + if ($this->_savedPrecision != ini_get('precision')) { + ini_set('precision',$this->_savedPrecision); + } } - /** - * 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() + 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; - } + /** + * 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() + /** + * __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 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']; - } + /** + * 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() + /** + * 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() + /** + * 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() + /** + * 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/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() + /** + * Enable calculation cache + */ + public function enableCalculationCache() { + $this->setCalculationCacheEnabled(TRUE); + } // function enableCalculationCache() - /** - * Disable calculation cache - */ - public function disableCalculationCache() { - $this->setCalculationCacheEnabled(FALSE); - } // function disableCalculationCache() + /** + * 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 + */ + 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() + /** + * 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() + /** + * 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() + /** + * 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); - } + /** + * 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(); + 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']; } + // 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; - } - } - } - } - } + $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() + 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; - } + 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); - } - } + 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; - } + 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) { - 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'; - } + 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'; - } - } + 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() + return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator); + } // 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) { - 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'; - } - } + 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'; - } - } + 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() + 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; - } + 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(); - } + /** + * 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() + 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() + /** + * 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 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; - } + /** + * 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; + $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; - } + self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; + } - // Execute the calculation for the cell formula + // 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()); - } + 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 ((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( + 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(); + /** + * 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() + // 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(); + /** + * 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()); - } + // 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; + // Reset calculation cacheing to its previous state + $this->_calculationCacheEnabled = $resetCache; - return $result; - } // function calculateFormula() + 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; - } - } + 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; + /** + * 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); + // 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"; + $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; - } - } + 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(); + // 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); - } + // Save to calculation cache + if ($cellID !== NULL) { + $this->saveValueToCache($wsCellReference, $cellValue); + } - // Return the calculated value - return $cellValue; - } // function _calculateFormulaValue() + // 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; - } + /** + * 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; - } + 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() + 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() + /** + * 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]); - } - } - } - } + /** + * 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() + 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; - } - } - } + /** + * 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() + 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); - } + /** + * 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() + 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); - } + /** + * 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() + 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(','))'); + 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"); - } - } - } + // 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() + return $formula; + } // function _convertMatrixReferences() - private static function _mkMatrix() { - return func_get_args(); - } // function _mkMatrix() + 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 - ); + // 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); + // 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 - ); + // 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; - } + // 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; + // 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'; + $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) { + // 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; + 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? + } 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; + 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? + } 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; + 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
'; - $stack->push('Brace', '('); - ++$index; + } elseif ($opCharacter == '(' && !$expectingOperator) { +// echo 'Element is an Opening Bracket
'; + $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
'; + } 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
'; - if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { - $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*\))/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
'; - // 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 (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { + $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*\))/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
'; + // 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"); - } - } + // 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
'; - // 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; - } - } + $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
'; + // 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
'; - // 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)) { -// echo 'Casting '.$val.' to float
'; - $val = (float) $val; - } else { -// echo 'Casting '.$val.' to integer
'; - $val = (integer) $val; - } - } elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) { - $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) { -// echo 'Element '.$localeConstant.' is an Excel Constant
'; - $val = self::$_ExcelConstants[$localeConstant]; - } - $details = array('type' => 'Value', 'value' => $val, 'reference' => NULL); - if ($localeConstant) { $details['localeValue'] = $localeConstant; } - $output[] = $details; - } - $index += $length; + $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)) { +// echo 'Casting '.$val.' to float
'; + $val = (float) $val; + } else { +// echo 'Casting '.$val.' to integer
'; + $val = (integer) $val; + } + } elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) { + $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) { +// echo 'Element '.$localeConstant.' is an Excel Constant
'; + $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
'; - 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
'; - 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; - } - } - } + } 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
'; + 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
'; + 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() + 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; - } + 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; + // 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; + // 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 '
'; - $token = $tokenData['value']; -// echo 'Token is '.$token.'
'; - // 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
'; - // 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'); + // Loop through each token in turn + foreach ($tokens as $tokenData) { +// print_r($tokenData); +// echo '
'; + $token = $tokenData['value']; +// echo 'Token is '.$token.'
'; + // 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
'; + // 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); + $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)); - } + // 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(); - } - } + // 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); - } + $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; - } + 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
'; - 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
'; - $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg)); - $multiplier = -1; - } else { -// echo 'Token is a percentile operator
'; - $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); - } + // 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
'; + 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
'; + $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg)); + $multiplier = -1; + } else { +// echo 'Token is a percentile operator
'; + $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
'; - if (isset($matches[8])) { -// echo 'Reference is a Range of cells
'; - 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].'
'; - $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
'; - $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
'; - 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].'
'; - $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
'; - $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); + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) { + $cellRef = NULL; +// echo 'Element '.$token.' is a Cell reference
'; + if (isset($matches[8])) { +// echo 'Reference is a Range of cells
'; + 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].'
'; + $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
'; + $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
'; + 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].'
'; + $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
'; + $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
'; - $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
'; - $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 '
'; - 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)); - } + // 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
'; + $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
'; + $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 '
'; + 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.'
'; - $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
'; - $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
'; - $namedRange = $matches[6]; -// echo 'Named Range is '.$namedRange.'
'; - $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']; + } 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.'
'; + $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
'; + $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
'; + $namedRange = $matches[6]; +// echo 'Named Range is '.$namedRange.'
'; + $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() +// 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; - } - } - } + 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() + // 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; - } + 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); } + // 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); - } + // 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); - } - } + if (is_string($operand2)) { + $operand2 = strtoupper($operand2); + } + } - $useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE; + $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 '=': + // 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; - } + 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; - } + // 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) - { + /** + * 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); - } + 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; + 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); + // 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) || + 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; - } - } - } + $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() + // 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() + // 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 (); + /** + * 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); - } +// 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; - } - } - } - } + // 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() + // 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 (); + /** + * 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.')
'; - if ($pSheet !== NULL) { - $pSheetName = $pSheet->getTitle(); -// echo 'Current sheet name is '.$pSheetName.'
'; -// echo '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); - } +// echo 'extractNamedRange('.$pRange.')
'; + if ($pSheet !== NULL) { + $pSheetName = $pSheet->getTitle(); +// echo 'Current sheet name is '.$pSheetName.'
'; +// echo '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? - $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().'
'; + // 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().'
'; -// if ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) { -// if (!$namedRange->getLocalOnly()) { -// $pSheet = $namedRange->getWorksheet(); -// } else { -// return $returnValue; -// } -// } - } else { - return PHPExcel_Calculation_Functions::REF(); - } +// 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.'
'; - $cellValue = NULL; - if ($pSheet->cellExists($reference)) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } - } -// print_r($returnValue); -// echo '
'; - } + // 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.'
'; + $cellValue = NULL; + if ($pSheet->cellExists($reference)) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } + } +// print_r($returnValue); +// echo '
'; + } - // Return - return $returnValue; - } // function extractNamedRange() + // 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() + /** + * 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'] - ); - } - } + /** + * 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() + // 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 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; - } - } + /** + * 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() + // Return + return $returnValue; + } // function listFunctionNames() -} // class PHPExcel_Calculation +} // class PHPExcel_Calculation diff --git a/Classes/PHPExcel/DocumentSecurity.php b/Classes/PHPExcel/DocumentSecurity.php index 0955019..0887a2c 100644 --- a/Classes/PHPExcel/DocumentSecurity.php +++ b/Classes/PHPExcel/DocumentSecurity.php @@ -76,11 +76,11 @@ class PHPExcel_DocumentSecurity } /** - * 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 @@ class PHPExcel_DocumentSecurity * * @return boolean */ - function getLockRevision() + public function getLockRevision() { return $this->_lockRevision; } @@ -103,7 +103,7 @@ class PHPExcel_DocumentSecurity * @param boolean $pValue * @return PHPExcel_DocumentSecurity */ - function setLockRevision($pValue = false) + public function setLockRevision($pValue = false) { $this->_lockRevision = $pValue; return $this; @@ -114,7 +114,7 @@ class PHPExcel_DocumentSecurity * * @return boolean */ - function getLockStructure() + public function getLockStructure() { return $this->_lockStructure; } @@ -125,7 +125,7 @@ class PHPExcel_DocumentSecurity * @param boolean $pValue * @return PHPExcel_DocumentSecurity */ - function setLockStructure($pValue = false) + public function setLockStructure($pValue = false) { $this->_lockStructure = $pValue; return $this; @@ -136,7 +136,7 @@ class PHPExcel_DocumentSecurity * * @return boolean */ - function getLockWindows() + public function getLockWindows() { return $this->_lockWindows; } @@ -147,7 +147,7 @@ class PHPExcel_DocumentSecurity * @param boolean $pValue * @return PHPExcel_DocumentSecurity */ - function setLockWindows($pValue = false) + public function setLockWindows($pValue = false) { $this->_lockWindows = $pValue; return $this; @@ -158,7 +158,7 @@ class PHPExcel_DocumentSecurity * * @return string */ - function getRevisionsPassword() + public function getRevisionsPassword() { return $this->_revisionsPassword; } @@ -170,7 +170,7 @@ class PHPExcel_DocumentSecurity * @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 @@ class PHPExcel_DocumentSecurity * * @return string */ - function getWorkbookPassword() + public function getWorkbookPassword() { return $this->_workbookPassword; } @@ -196,7 +196,7 @@ class PHPExcel_DocumentSecurity * @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 9e30ae8..d0c9a44 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 @@ class PHPExcel_Helper_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();; diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php index a72b929..7226d4a 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 _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(); - } - } + 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']); + 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) { - 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); + 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() + 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; - } - } + 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() + 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 _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(); + 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() + $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'); + 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('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('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); + } 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() + 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; + 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; - } - } + 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; - } + if (empty($seriesVal)) { + $seriesVal = NULL; + } - return array( 'formatCode' => $formatCode, - 'pointCount' => $pointCount, - 'dataValues' => $seriesVal - ); - } // function _chartDataSeriesValues() + return array( 'formatCode' => $formatCode, + 'pointCount' => $pointCount, + 'dataValues' => $seriesVal + ); + } // function _chartDataSeriesValues() - private static function _chartDataSeriesValuesMultiLevel($seriesValueSet,$dataType='n') { - $seriesVal = array(); - $formatCode = ''; - $pointCount = 0; + 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; - } - } - } + 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() + return array( 'formatCode' => $formatCode, + 'pointCount' => $pointCount, + 'dataValues' => $seriesVal + ); + } // function _chartDataSeriesValuesMultiLevel() - private static function _parseRichText($titleDetailPart = null) { - $value = new PHPExcel_RichText(); + 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"]); - } + 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)); - } + $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) ) ); - } + $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); - } + $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); - } + $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); - } - } + $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); - } - } + $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); - } - } - } - } + $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; - } + 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'); - } - } + 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; - } + 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 _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 9647e12..5d3c1c9 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 @@ class PHPExcel_Reader_Excel2007_Theme * @return string */ public function getColourSchemeName() { - return $this->_colourSchemeName; + return $this->_colourSchemeName; } /** @@ -102,23 +102,23 @@ class PHPExcel_Reader_Excel2007_Theme * @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 f183829..9b2338c 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 4f23c7b..9130b45 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 ebda1b2..5a6c043 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 c3fe230..75260c9 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 + /** 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 $_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', - ); + /* + * 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; + /* + * 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() + /** + * 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() + /** + * 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; - } + /** + * 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); - } + // 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; + $timezoneAdjustment = ($adjustToTimezone) ? + PHPExcel_Shared_TimeZone::getTimezoneAdjustment($timezone, $returnValue) : + 0; - // Return - return $returnValue + $timezoneAdjustment; - } // function ExcelToPHP() + // 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); + /** + * 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); + $dateObj = date_create('1-Jan-1970+'.$days.' days'); + $dateObj->setTime($hours,$minutes,$seconds); - return $dateObj; - } // function ExcelToPHPObject() + 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); + /** + * 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() + 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; - } + /** + * 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; - } + // 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; + // 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; + $excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400; - return (float) $excelDate + $excelTime; - } // function FormattedPHPToExcel() + 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 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() + /** + * 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'; + 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; + /** + * 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; - } + // 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; - } + // 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() + // 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; + /** + * 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); + $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; - } + 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 @@ class PHPExcel_Shared_Date } 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 aeae3bd..311d9be 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 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 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(); + /** + * 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; - } + 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; - } + 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(); + /** + * 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']; + 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; - } + } 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); + // Round pixels to closest integer + $colWidth = (int) round($colWidth); - return $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 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 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 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; - } - } + /** + * 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) - { + /** + * 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 @@ class PHPExcel_Shared_Drawing // Return image-object return $image; - } + } } diff --git a/Classes/PHPExcel/Shared/Escher.php b/Classes/PHPExcel/Shared/Escher.php index 88cb1c6..67b346e 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 b7c9fd9..ef855d7 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 c60c641..efa1683 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 97792af..97136ee 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; + /** + * Parent Shape Group Container + * + * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer + */ + private $_parent; - /** - * Is this a group shape? - * - * @var boolean - */ - private $_spgr = false; + /** + * Is this a group shape? + * + * @var boolean + */ + private $_spgr = false; - /** - * Shape type - * - * @var int - */ - private $_spType; + /** + * Shape type + * + * @var int + */ + private $_spType; - /** - * Shape flag - * - * @var int - */ - private $_spFlag; + /** + * Shape flag + * + * @var int + */ + private $_spFlag; - /** - * Shape index (usually group shape has index 0, and the rest: 1,2,3...) - * - * @var boolean - */ - private $_spId; + /** + * 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; + /** + * Array of options + * + * @var array + */ + private $_OPT; - /** - * Cell coordinates of upper-left corner of shape, e.g. 'A1' - * - * @var string - */ - private $_startCoordinates; + /** + * 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; + /** + * 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; + /** + * 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; + /** + * 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; + /** + * 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; + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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 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; + /** + * 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(); - } + $parent = $this->getParent(); + while ($parent instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) { + ++$nestingLevel; + $parent = $parent->getParent(); + } - return $nestingLevel; - } + return $nestingLevel; + } } diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer.php index b5dd3ee..dae6a5a 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; + /** + * 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 drawings saved + * + * @var int + */ + private $_cDgSaved; - /** - * Total number of shapes saved (including group shapes) - * - * @var int - */ - private $_cSpSaved; + /** + * Total number of shapes saved (including group shapes) + * + * @var int + */ + private $_cSpSaved; - /** - * BLIP Store Container - * - * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer - */ - private $_bstoreContainer; + /** + * 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 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(); + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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 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; - } + /** + * 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 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; - } + /** + * Get identifier clusters + * + * @return array + */ + public function getIDCLs() + { + return $this->_IDCLs; + } - /** - * Set identifier clusters. array( => , ...) - * - * @param array $pValue - */ - public function setIDCLs($pValue) - { - $this->_IDCLs = $pValue; - } + /** + * Set identifier clusters. array( => , ...) + * + * @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 468ca24..390f09b 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 0b1239d..0fac1b8 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 80e83bc..4fd743f 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 5564c6b..115cc3a 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(); + /** + * 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(); + $columnDimensions = $sheet->getColumnDimensions(); - // first find the true column width in pixels (uncollapsed and unhidden) - if ( isset($columnDimensions[$col]) and $columnDimensions[$col]->getWidth() != -1 ) { + // 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); + // 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) { + } 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); + // then we have default column dimension with explicit width + $defaultColumnDimension = $sheet->getDefaultColumnDimension(); + $width = $defaultColumnDimension->getWidth(); + $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); - } else { + } else { - // we don't even have any default column dimension. Width depends on default font - $pixelWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($font, true); - } + // 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; - } + // now find the effective column width in pixels + if (isset($columnDimensions[$col]) and !$columnDimensions[$col]->getVisible()) { + $effectivePixelWidth = 0; + } else { + $effectivePixelWidth = $pixelWidth; + } - return $effectivePixelWidth; - } + 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(); + /** + * 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(); + $rowDimensions = $sheet->getRowDimensions(); - // first find the true row height in pixels (uncollapsed and unhidden) - if ( isset($rowDimensions[$row]) and $rowDimensions[$row]->getRowHeight() != -1) { + // 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 + // 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) { + } 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); + // then we have a default row dimension with explicit height + $defaultRowDimension = $sheet->getDefaultRowDimension(); + $rowHeight = $defaultRowDimension->getRowHeight(); + $pixelRowHeight = PHPExcel_Shared_Drawing::pointsToPixels($rowHeight); - } else { + } 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); + // 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; - } + // now find the effective row height in pixels + if ( isset($rowDimensions[$row]) and !$rowDimensions[$row]->getVisible() ) { + $effectivePixelRowHeight = 0; + } else { + $effectivePixelRowHeight = $pixelRowHeight; + } - return $effectivePixelRowHeight; - } + 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; + /** + * 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)); - } + // 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 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)); + // correct for offsetX in endcell + $distanceX -= (int) floor(self::sizeCol($sheet, $endColumn) * (1 - $endOffsetX / 1024)); - return $distanceX; - } + 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; + /** + * 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); - } + // 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 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)); + // correct for offsetX in endcell + $distanceY -= (int) floor(self::sizeRow($sheet, $endRow) * (1 - $endOffsetY / 256)); - return $distanceY; - } + 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; + /** + * 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; + $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 + // 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; - } + // 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; + $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 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; - } + // 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; - } + // 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 + // 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); + $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, - ); + $twoAnchor = array( + 'startCoordinates' => $startCoordinates, + 'startOffsetX' => $x1, + 'startOffsetY' => $y1, + 'endCoordinates' => $endCoordinates, + 'endOffsetX' => $x2, + 'endOffsetY' => $y2, + ); - return $twoAnchor; - } + return $twoAnchor; + } } diff --git a/Classes/PHPExcel/Shared/File.php b/Classes/PHPExcel/Shared/File.php index 8dfb66e..8c3012d 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; + /* + * 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() + /** + * 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() + /** + * 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); + /** + * 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); - } - } + $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 = ''; + /** + * 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); - } + // 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); - } + // 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; - } + // 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); - } - } - } + /** + * 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); } - } + // 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)); - } + // 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; - } + 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 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 a59aa50..43451cb 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'; + /* 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, - ); + 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; + /** 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'; + // 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 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 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 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 GEORGIA = 'georgia.ttf'; + const GEORGIA_BOLD = 'georgiab.ttf'; + const GEORGIA_ITALIC = 'georgiai.ttf'; + const GEORGIA_BOLD_ITALIC = 'georgiaz.ttf'; - const IMPACT = 'impact.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 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 LUCIDA_CONSOLE = 'lucon.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_BOLD = 'palab.ttf'; - const PALATINO_LINOTYPE_ITALIC = 'palai.ttf'; - const PALATINO_LINOTYPE_BOLD_ITALIC = 'palabi.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 SYMBOL = 'symbol.ttf'; - const TAHOMA = 'tahoma.ttf'; - const TAHOMA_BOLD = 'tahomabd.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 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 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: - *
    - *
  • C:/Windows/Fonts/
  • - *
  • /usr/share/fonts/truetype/
  • - *
  • ~/.fonts/
  • - *
- * - * @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; - } + 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(); - } + * AutoSize method + * + * @var string + */ + private static $autoSizeMethod = self::AUTOSIZE_METHOD_APPROX; - // 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 - } + /** + * Path to folder containing TrueType font .ttf files + * + * @var string + */ + private static $trueTypeFontPath = null; - // Try to get the exact text width in pixels + /** + * 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: + *
    + *
  • C:/Windows/Fonts/
  • + *
  • /usr/share/fonts/truetype/
  • + *
  • ~/.fonts/
  • + *
+ * + * @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 @@ class PHPExcel_Shared_Font 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); + // Convert from pixel width to column width + $columnWidth = PHPExcel_Shared_Drawing::pixelsToCellDimension($columnWidth, $defaultFont); - // Return - return round($columnWidth, 6); - } + // 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'); - } + /** + * 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); + // 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]; + // 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); + // Consider the rotation when calculating the width + $textWidth = max($lowerRightCornerX - $upperLeftCornerX, $upperRightCornerX - $lowerLeftCornerX); - return $textWidth; - } + 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(); + /** + * 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 + // 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 '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; + 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 + break; - default: - // just assume Calibri - $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); - $columnWidth = $columnWidth * $fontSize / 11; // 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; - // 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 - } - } + default: + // just assume Calibri + $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size + break; + } - // pixel width is an integer - return (int) $columnWidth; - } + // 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 + } + } - /** - * 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); - } + // pixel width is an integer + return (int) $columnWidth; + } - /** - * 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 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 centimeter size - * - * @param int $sizeInCm Font size (in centimeters) - * @return int Size (in pixels) - */ - public static function centimeterSizeToPixels($sizeInCm = 1) { - return ($sizeInCm * 37.795275591); - } + /** + * 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); + } - /** - * 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'); - } + /** + * 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); + } - $name = $font->getName(); - $bold = $font->getBold(); - $italic = $font->getItalic(); + /** + * 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'); + } - // 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; + $name = $font->getName(); + $bold = $font->getBold(); + $italic = $font->getItalic(); - case 'Calibri': - $fontFile = ( - $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD) - : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI) - ); - break; + // 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 'Courier New': - $fontFile = ( - $bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD) - : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW) - ); - break; + case 'Calibri': + $fontFile = ( + $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD) + : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI) + ); + break; - case 'Comic Sans MS': - $fontFile = ( - $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS - ); - 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 'Georgia': - $fontFile = ( - $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD) - : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA) - ); - break; + case 'Comic Sans MS': + $fontFile = ( + $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS + ); + break; - case 'Impact': - $fontFile = self::IMPACT; - break; + case 'Georgia': + $fontFile = ( + $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD) + : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA) + ); + 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 'Impact': + $fontFile = self::IMPACT; + break; - case 'Lucida Console': - $fontFile = self::LUCIDA_CONSOLE; - 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 Sans Unicode': - $fontFile = self::LUCIDA_SANS_UNICODE; - break; + case 'Lucida Console': + $fontFile = self::LUCIDA_CONSOLE; + break; - case 'Microsoft Sans Serif': - $fontFile = self::MICROSOFT_SANS_SERIF; - break; + case 'Lucida Sans Unicode': + $fontFile = self::LUCIDA_SANS_UNICODE; + 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 'Microsoft Sans Serif': + $fontFile = self::MICROSOFT_SANS_SERIF; + break; - case 'Symbol': - $fontFile = self::SYMBOL; - 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 'Tahoma': - $fontFile = ( - $bold ? self::TAHOMA_BOLD : self::TAHOMA - ); - break; + case 'Symbol': + $fontFile = self::SYMBOL; + 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 'Tahoma': + $fontFile = ( + $bold ? self::TAHOMA_BOLD : self::TAHOMA + ); + 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 '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 'Verdana': - $fontFile = ( - $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD) - : ($italic ? self::VERDANA_ITALIC : self::VERDANA) - ); - 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; - default: - throw new PHPExcel_Exception('Unknown font name "'. $name .'". Cannot map to TrueType font file'); - break; - } + case 'Verdana': + $fontFile = ( + $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD) + : ($italic ? self::VERDANA_ITALIC : self::VERDANA) + ); + break; - $fontFile = self::$trueTypeFontPath . $fontFile; + default: + throw new PHPExcel_Exception('Unknown font name "'. $name .'". Cannot map to TrueType font file'); + break; + } - // Check if file actually exists - if (!file_exists($fontFile)) { - throw New PHPExcel_Exception('TrueType Font file not found'); - } + $fontFile = self::$trueTypeFontPath . $fontFile; - return $fontFile; - } + // Check if file actually exists + if (!file_exists($fontFile)) { + throw New PHPExcel_Exception('TrueType Font file not found'); + } - /** - * 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; - } - } + return $fontFile; + } - /** - * 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']; + /** + * 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; + } + } - } 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; + /** + * 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']; - // Round pixels to closest integer - if ($pPixels) { - $columnWidth = (int) round($columnWidth); - } - } + } 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; - return $columnWidth; - } + // Round pixels to closest integer + if ($pPixels) { + $columnWidth = (int) round($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; + return $columnWidth; + } - case 9: - // inspection of Arial 9 workbook says 12.00pt ~16px - $rowHeight = 12; - break; + /** + * 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 8: - // inspection of Arial 8 workbook says 11.25pt ~15px - $rowHeight = 11.25; - break; + case 9: + // inspection of Arial 9 workbook says 12.00pt ~16px + $rowHeight = 12; + break; - case 7: - // inspection of Arial 7 workbook says 9.00pt ~12px - $rowHeight = 9; - break; + case 8: + // inspection of Arial 8 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; - case 6: - case 5: - // inspection of Arial 5,6 workbook says 8.25pt ~11px - $rowHeight = 8.25; - break; + case 7: + // inspection of Arial 7 workbook says 9.00pt ~12px + $rowHeight = 9; + break; - case 4: - // inspection of Arial 4 workbook says 6.75pt ~9px - $rowHeight = 6.75; - break; + case 6: + case 5: + // inspection of Arial 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; - case 3: - // inspection of Arial 3 workbook says 6.00pt ~8px - $rowHeight = 6; - break; + case 4: + // inspection of Arial 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; - case 2: - case 1: - // inspection of Arial 1,2 workbook says 5.25pt ~7px - $rowHeight = 5.25; - break; + case 3: + // inspection of Arial 3 workbook says 6.00pt ~8px + $rowHeight = 6; + break; - default: - // use Arial 10 workbook as an approximation, extrapolation - $rowHeight = 12.75 * $font->getSize() / 10; - break; - } - break; + case 2: + case 1: + // inspection of Arial 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; - case 'Calibri': - switch ($font->getSize()) { - case 11: - // inspection of Calibri 11 workbook says 15.00pt ~20px - $rowHeight = 15; - break; + default: + // use Arial 10 workbook as an approximation, extrapolation + $rowHeight = 12.75 * $font->getSize() / 10; + break; + } + break; - case 10: - // inspection of Calibri 10 workbook says 12.75pt ~17px - $rowHeight = 12.75; - break; + case 'Calibri': + switch ($font->getSize()) { + case 11: + // inspection of Calibri 11 workbook says 15.00pt ~20px + $rowHeight = 15; + break; - case 9: - // inspection of Calibri 9 workbook says 12.00pt ~16px - $rowHeight = 12; - break; + case 10: + // inspection of Calibri 10 workbook says 12.75pt ~17px + $rowHeight = 12.75; + break; - case 8: - // inspection of Calibri 8 workbook says 11.25pt ~15px - $rowHeight = 11.25; - break; + case 9: + // inspection of Calibri 9 workbook says 12.00pt ~16px + $rowHeight = 12; + break; - case 7: - // inspection of Calibri 7 workbook says 9.00pt ~12px - $rowHeight = 9; - break; + case 8: + // inspection of Calibri 8 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; - case 6: - case 5: - // inspection of Calibri 5,6 workbook says 8.25pt ~11px - $rowHeight = 8.25; - break; + case 7: + // inspection of Calibri 7 workbook says 9.00pt ~12px + $rowHeight = 9; + break; - case 4: - // inspection of Calibri 4 workbook says 6.75pt ~9px - $rowHeight = 6.75; - break; + case 6: + case 5: + // inspection of Calibri 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; - case 3: - // inspection of Calibri 3 workbook says 6.00pt ~8px - $rowHeight = 6.00; - break; + case 4: + // inspection of Calibri 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; - case 2: - case 1: - // inspection of Calibri 1,2 workbook says 5.25pt ~7px - $rowHeight = 5.25; - break; + case 3: + // inspection of Calibri 3 workbook says 6.00pt ~8px + $rowHeight = 6.00; + break; - default: - // use Calibri 11 workbook as an approximation, extrapolation - $rowHeight = 15 * $font->getSize() / 11; - break; - } - break; + case 2: + case 1: + // inspection of Calibri 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; - case 'Verdana': - switch ($font->getSize()) { - case 10: - // inspection of Verdana 10 workbook says 12.75pt ~17px - $rowHeight = 12.75; - break; + default: + // use Calibri 11 workbook as an approximation, extrapolation + $rowHeight = 15 * $font->getSize() / 11; + break; + } + break; - case 9: - // inspection of Verdana 9 workbook says 11.25pt ~15px - $rowHeight = 11.25; - break; + case 'Verdana': + switch ($font->getSize()) { + case 10: + // inspection of Verdana 10 workbook says 12.75pt ~17px + $rowHeight = 12.75; + break; - case 8: - // inspection of Verdana 8 workbook says 10.50pt ~14px - $rowHeight = 10.50; - break; + case 9: + // inspection of Verdana 9 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; - case 7: - // inspection of Verdana 7 workbook says 9.00pt ~12px - $rowHeight = 9.00; - break; + case 8: + // inspection of Verdana 8 workbook says 10.50pt ~14px + $rowHeight = 10.50; + break; - case 6: - case 5: - // inspection of Verdana 5,6 workbook says 8.25pt ~11px - $rowHeight = 8.25; - break; + case 7: + // inspection of Verdana 7 workbook says 9.00pt ~12px + $rowHeight = 9.00; + break; - case 4: - // inspection of Verdana 4 workbook says 6.75pt ~9px - $rowHeight = 6.75; - break; + case 6: + case 5: + // inspection of Verdana 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; - case 3: - // inspection of Verdana 3 workbook says 6.00pt ~8px - $rowHeight = 6; - break; + case 4: + // inspection of Verdana 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; - case 2: - case 1: - // inspection of Verdana 1,2 workbook says 5.25pt ~7px - $rowHeight = 5.25; - break; + case 3: + // inspection of Verdana 3 workbook says 6.00pt ~8px + $rowHeight = 6; + break; - default: - // use Verdana 10 workbook as an approximation, extrapolation - $rowHeight = 12.75 * $font->getSize() / 10; - break; - } - break; + case 2: + case 1: + // inspection of Verdana 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; - default: - // just use Calibri as an approximation - $rowHeight = 15 * $font->getSize() / 11; - break; - } + default: + // use Verdana 10 workbook as an approximation, extrapolation + $rowHeight = 12.75 * $font->getSize() / 10; + break; + } + break; - return $rowHeight; - } + 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 cfbaa53..31a0b64 100644 --- a/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php @@ -1,149 +1,149 @@ L = $A->getArray(); - $this->m = $A->getRowDimension(); + /** + * 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($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() + 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() + /** + * 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() + /** + * 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(); + /** + * 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 = 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]; - } - } - } + 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() + 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 +} // class CholeskyDecomposition diff --git a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php index 2a696d0..386d6c1 100644 --- a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php @@ -1,862 +1,862 @@ 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; - } + /** + * 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; - } - } + // 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; - } + $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); + /** + * 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; - } + 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; - } - } - } - } + // 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; + /** + * 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; - } - } + 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]; - } - } - } - } - } + // 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; - } - } + /** + * 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; + /** + * 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]); - } - } + 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) + // 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; - } + // 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 + 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]; - } - } - } + // 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 + // 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(); + /** + * 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]); - } - } + $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(); - } - } + 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 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 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 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); - } + /** + * 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 +} // class EigenvalueDecomposition diff --git a/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php b/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php index 08e500c..a4b2266 100644 --- a/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php @@ -1,258 +1,258 @@ = 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 1e7c334..8d5e39d 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 7538462..17c4435 100644 --- a/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php @@ -1,234 +1,234 @@ = 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."; + const MatrixRankException = "Can only perform operation on full-rank matrix."; - /** - * Array for internal storage of decomposition. - * @var array - */ - private $QR = array(); + /** + * Array for internal storage of decomposition. + * @var array + */ + private $QR = array(); - /** - * Row dimension. - * @var integer - */ - private $m; + /** + * Row dimension. + * @var integer + */ + private $m; - /** - * Column dimension. - * @var integer - */ - private $n; + /** + * Column dimension. + * @var integer + */ + private $n; - /** - * Array for internal storage of diagonal of R. - * @var array - */ - private $Rdiag = array(); + /** + * 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() + /** + * 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() + /** + * 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 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() + /** + * 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() + /** + * 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() + /** + * 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 +} // PHPExcel_Shared_JAMA_class QRDecomposition diff --git a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php index a4b096c..76c4786 100644 --- a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php @@ -1,526 +1,526 @@ = 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 U. + * @var array + */ + private $U = array(); - /** - * Internal storage of V. - * @var array - */ - private $V = array(); + /** + * Internal storage of V. + * @var array + */ + private $V = array(); - /** - * Internal storage of singular values. - * @var array - */ - private $s = array(); + /** + * Internal storage of singular values. + * @var array + */ + private $s = 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; - /** - * 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) { + /** + * 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)); + // 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) { + // 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]; - } + 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]; - } - } + 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 ($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]; - } - } - } - } + 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; - } - } - } + // 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; - } - } + // 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); + // 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

= -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; + 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

= -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 + // 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 + } // 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 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 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 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); - } + /** + * 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 + * + * @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]; - } + /** + * 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; - } + /** + * 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 +} // class SingularValueDecomposition diff --git a/Classes/PHPExcel/Shared/JAMA/utils/Error.php b/Classes/PHPExcel/Shared/JAMA/utils/Error.php index e73252b..ff51ccc 100644 --- a/Classes/PHPExcel/Shared/JAMA/utils/Error.php +++ b/Classes/PHPExcel/Shared/JAMA/utils/Error.php @@ -1,10 +1,10 @@ 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 9796282..f114906 100644 --- a/Classes/PHPExcel/Shared/OLE.php +++ b/Classes/PHPExcel/Shared/OLE.php @@ -37,495 +37,495 @@ $GLOBALS['_OLE_INSTANCES'] = array(); */ 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; + 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; + /** + * 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(); + /** + * 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; + /** + * Root directory of OLE container + * @var OLE_PPS_Root + */ + public $root; - /** - * Big Block Allocation Table - * @var array (blockId => nextBlockId) - */ - public $bbat; + /** + * Big Block Allocation Table + * @var array (blockId => nextBlockId) + */ + public $bbat; - /** - * Short Block Allocation Table - * @var array (blockId => nextBlockId) - */ - public $sbat; + /** + * 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 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; + /** + * 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; + /** + * 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)); + $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); + // 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); + // 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(); + // 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); - } + // 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 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 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); + // 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); + $this->_readPpsWks($directoryFirstBlockId); - return true; - } + 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; - } + /** + * @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; - } + /** + * 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'])); + // 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'); - } + $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 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 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; - } + /** + * 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; + /** + * 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)) { + // check if the PPS tree (starting from root) is complete + if (isset($this->root) && + $this->_ppsTreeComplete($this->root->No)) { - break; - } - } - fclose($fh); + 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; - } - } - } - } + // 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; - } + 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)); - } + /** + * 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 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; - } + /** + * 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); - } + /** + * 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 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; - } + /** + * 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 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"; - } + /** + * 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); + // 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; + // 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); + $high_part = floor($big_date / $factor); + // lower 4 bytes + $low_part = floor((($big_date / $factor) - $high_part) * $factor); - // Make HEX string - $res = ''; + // 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; - } + 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"); - } + /** + * 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)); + // 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; + $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; + // 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); - } + // 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 03a9e48..10f3f4b 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; + /** + * The OLE container of the file that is being read. + * @var OLE + */ + public $ole; - /** - * Parameters specified by fopen(). - * @var array - */ - public $params; + /** + * Parameters specified by fopen(). + * @var array + */ + public $params; - /** - * The binary data of the file. - * @var string - */ - public $data; + /** + * The binary data of the file. + * @var string + */ + public $data; - /** - * The file pointer. - * @var int byte offset - */ - public $pos; + /** + * 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; - } + /** + * 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']])) { + // 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']]; + 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) { + $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']); - } + // 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; - } + if ($options & STREAM_USE_PATH) { + $openedPath = $path; + } - return true; - } + return true; + } - /** - * Implements support for fclose(). - * - */ - public function stream_close() - { - $this->ole = null; - unset($GLOBALS['_OLE_INSTANCES']); - } + /** + * 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 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); - } + /** + * 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; - } + /** + * 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 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), - ); - } + /** + * 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 ) + // 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 4db0ae4..80875f9 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 index + * @var integer + */ + public $No; - /** - * The PPS name (in Unicode) - * @var string - */ - public $Name; + /** + * The PPS name (in Unicode) + * @var string + */ + public $Name; - /** - * The PPS type. Dir, Root or File - * @var integer - */ - public $Type; + /** + * 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 previous PPS + * @var integer + */ + public $PrevPps; - /** - * The index of the next PPS - * @var integer - */ - public $NextPps; + /** + * 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; + /** + * 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 $Time1st; - /** - * A timestamp - * @var integer - */ - public $Time2nd; + /** + * A timestamp + * @var integer + */ + public $Time2nd; - /** - * Starting block (small or big) for this PPS's data inside the container - * @var integer - */ - public $_StartBlock; + /** + * 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 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; + /** + * 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(); + /** + * 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; + /** + * 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; - } - } + /** + * 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 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"); + /** + * 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; - } + $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++); + /** + * 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; - } + } + return $cnt; + } } diff --git a/Classes/PHPExcel/Shared/OLE/PPS/File.php b/Classes/PHPExcel/Shared/OLE/PPS/File.php index f061f56..f0be587 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 eb929d2..cbf0110 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 b50fd05..9a8729f 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 @@ defined('IDENTIFIER_OLE') || 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 ($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 ($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; - } + 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); - } - } + $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; + $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; - } + $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; + $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; + $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); + // read the directory stream + $block = $this->rootStartBlock; + $this->entry = $this->_readData($block); - $this->_readPropertySets(); - } + $this->_readPropertySets(); + } - /** - * Extract binary stream data - * - * @return string - */ - public function getStream($stream) - { - if ($stream === NULL) { - return null; - } + /** + * Extract binary stream data + * + * @return string + */ + public function getStream($stream) + { + if ($stream === NULL) { + return null; + } - $streamData = ''; + $streamData = ''; - if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) { - $rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']); + if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) { + $rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']); - $block = $this->props[$stream]['startBlock']; + $block = $this->props[$stream]['startBlock']; - while ($block != -2) { - $pos = $block * self::SMALL_BLOCK_SIZE; - $streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE); + while ($block != -2) { + $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; - } else { - $numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE; - if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) { - ++$numBlocks; - } + 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 ''; + if ($numBlocks == 0) return ''; - $block = $this->props[$stream]['startBlock']; + $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); - } + 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; - } - } + 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 = ''; + /** + * 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; - } + 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; + /** + * 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); + // 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); + // 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]); + // 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); + // 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); + $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 ( - 'name' => $name, - 'type' => $type, - 'startBlock' => $startBlock, - 'size' => $size); + $this->props[] = array ( + 'name' => $name, + 'type' => $type, + 'startBlock' => $startBlock, + 'size' => $size); - // tmp helper to simplify checks - $upName = strtoupper($name); + // 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; - } + // 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
'; - $this->summaryInformation = count($this->props) - 1; - } + // Summary information + if ($name == chr(5) . 'SummaryInformation') { +// echo 'Summary Information
'; + $this->summaryInformation = count($this->props) - 1; + } - // Additional Document Summary information - if ($name == chr(5) . 'DocumentSummaryInformation') { -// echo 'Document Summary Information
'; - $this->documentSummaryInformation = count($this->props) - 1; - } + // Additional Document Summary information + if ($name == chr(5) . 'DocumentSummaryInformation') { +// echo 'Document Summary Information
'; + $this->documentSummaryInformation = count($this->props) - 1; + } - $offset += self::PROPERTY_STORAGE_BLOCK_SIZE; - } + $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; - } + /** + * 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 5b81e67..cafc4fa 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -327,7 +327,7 @@ } 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 @@ ,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 @@ 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 @@ ,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 @@ 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 @@ // ----- 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 @@ 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 @@ { $v_result = true; - // ----- Reset the file system cache + // ----- Reset the file system cache clearstatcache(); // ----- Reset the error handler @@ -1596,9 +1596,9 @@ 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 @@ 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 @@ 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 @@ 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 @@ // ----- 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 @@ // ----- 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 @@ // ----- 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 @@ // ----- 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 @@ $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 @@ // ----- 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 @@ // ----- 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 @@ // ----- Look for user callback abort if ($v_result1 == 2) { - break; + break; } } } @@ -3679,8 +3679,8 @@ 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 @@ 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 @@ // 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 @@ // 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 @@ { // ----- 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 @@ // ----- 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 @@ } } - // ----- 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 @@ // ----- Look for abort result if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; + $v_result = PCLZIP_ERR_USER_ABORTED; } } @@ -4076,7 +4076,7 @@ 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 @@ } } - // ----- 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 @@ // ----- Look for abort result if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; + $v_result = PCLZIP_ERR_USER_ABORTED; } } @@ -4191,7 +4191,7 @@ 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 @@ } - // ----- 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 @@ // ----- Look for abort result if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; + $v_result = PCLZIP_ERR_USER_ABORTED; } } @@ -4489,27 +4489,27 @@ { $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 @@ // ----- 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 @@ } } else { - $v_found = true; + $v_found = true; } // ----- Look for deletion @@ -4872,7 +4872,7 @@ // ----- 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 @@ // ----- 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 @@ // ----- 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 @@ // 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 @@ $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 db0707f..92c8b3f 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 . - * - * @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 . + * + * @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 7c69788..3d584c4 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+)'; + /** Constants */ + /** Regular Expressions */ + // Fraction + const STRING_REGEXP_FRACTION = '(-?)(\d+)\s+(\d+\/\d+)'; - /** - * Control characters array - * - * @var string[] - */ - private static $_controlCharacters = array(); + /** + * Control characters array + * + * @var string[] + */ + private static $_controlCharacters = array(); - /** - * SYLK Characters array - * - * $var array - */ - private static $_SYLKCharacters = array(); + /** + * SYLK Characters array + * + * $var array + */ + private static $_SYLKCharacters = array(); - /** - * Decimal separator - * - * @var string - */ - private static $_decimalSeparator; + /** + * Decimal separator + * + * @var string + */ + private static $_decimalSeparator; - /** - * Thousands separator - * - * @var string - */ - private static $_thousandsSeparator; + /** + * Thousands separator + * + * @var string + */ + private static $_thousandsSeparator; - /** - * Currency code - * - * @var string - */ - private static $_currencyCode; + /** + * Currency code + * + * @var string + */ + private static $_currencyCode; - /** - * Is mbstring extension avalable? - * - * @var boolean - */ - private static $_isMbstringEnabled; + /** + * Is mbstring extension avalable? + * + * @var boolean + */ + private static $_isMbstringEnabled; - /** - * Is iconv extension avalable? - * - * @var boolean - */ - private static $_isIconvEnabled; + /** + * 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 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 - ); - } + /** + * 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; - } + /** + * 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; + self::$_isMbstringEnabled = function_exists('mb_convert_encoding') ? + true : false; - return self::$_isMbstringEnabled; - } + return self::$_isMbstringEnabled; + } - /** - * Get whether iconv extension is available - * - * @return boolean - */ - public static function getIsIconvEnabled() - { - if (isset(self::$_isIconvEnabled)) { - return self::$_isIconvEnabled; - } + /** + * 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; - } + // 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 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; - } + // 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; - } + // 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; - } + // 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(); - } - } + 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 () - * element or in the shared string 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 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 () + * element or in the shared string 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 () - * element or in the shared string 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 ); - } + /** + * 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 () + * element or in the shared string 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; - } + /** + * 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; - } + if (self::getIsMbstringEnabled()) { + $value = mb_convert_encoding($value, 'UTF-8', 'UTF-8'); + return $value; + } - // else, no conversion - 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; - } + /** + * 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; - } + /** + * 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 (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'); + /** + * 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; + // option flags + $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? + 0x0001 : 0x0000; - // characters - $chars = self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); + // characters + $chars = self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); - $data = pack('vC', $ln, $opt) . $chars; - return $data; - } + $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); - } + /** + * 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 (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; - } + 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; - } + /** + * 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); - } + /** + * 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); - } + if (self::getIsIconvEnabled()) { + return iconv_strlen($value, $enc); + } - // else strlen - return strlen($value); - } + // 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'); - } + /** + * 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'); - } + if (self::getIsIconvEnabled()) { + return iconv_substr($pValue, $pStart, $pLength, 'UTF-8'); + } - // else substr - return substr($pValue, $pStart, $pLength); - } + // 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 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 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); - } + /** + * 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 @@ class PHPExcel_Shared_String return preg_split('/(?_calculateFormulaValue($fractionFormula); - return true; - } - return false; - } // function convertToNumberIfFraction() + /** + * 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']; + /** + * 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; - } + 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; - } + /** + * 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']; + /** + * 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; - } + 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; - } + /** + * 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']; + /** + * 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; - } + 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; - } + /** + * 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; - } + /** + * 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); - } + foreach (self::$_SYLKCharacters as $k => $v) { + $pValue = str_replace($k, $v, $pValue); + } - return $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; - } + /** + * 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 3aa1884..8e41732 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 8ec38e2..a17c112 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 @@ if (!defined('DEBUGMODE_ENABLED')) { * 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 4af9c3d..6a1dcc6 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 @@ require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/PCLZip/pclzip.lib.php'; class PHPExcel_Shared_ZipArchive { - /** constants */ - const OVERWRITE = 'OVERWRITE'; - const CREATE = 'CREATE'; - - - /** - * Temporary storage directory - * - * @var string - */ - private $_tempDir; - - /** - * Zip Archive Stream Handle - * - * @var string - */ - private $_zip; + /** constants */ + const OVERWRITE = 'OVERWRITE'; + const CREATE = 'CREATE'; /** - * Open a new zip archive - * - * @param string $fileName Filename for the zip archive - * @return boolean + * Temporary storage directory + * + * @var string */ - public function open($fileName) - { - $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + private $_tempDir; - $this->_zip = new PclZip($fileName); - - return true; - } + /** + * Zip Archive Stream Handle + * + * @var string + */ + private $_zip; /** - * Close this zip archive - * + * Open a new zip archive + * + * @param string $fileName Filename for the zip archive + * @return boolean */ - public function close() - { - } + public function open($fileName) + { + $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + + $this->_zip = new PclZip($fileName); + + return true; + } /** - * 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 + * Close this zip archive + * */ - public function addFromString($localname, $contents) - { - $filenameParts = pathinfo($localname); + public function close() + { + } - $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)); - } + /** + * 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); - unlink($this->_tempDir.'/'.$filenameParts["basename"]); - } + $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()) @@ -138,7 +135,7 @@ class PHPExcel_Shared_ZipArchive * @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 @@ class PHPExcel_Shared_ZipArchive $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 a5ceb1e..30b57be 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 @@ class PHPExcel_Shared_ZipStreamWrapper { 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 @@ class PHPExcel_Shared_ZipStreamWrapper { } /** - * 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 @@ class PHPExcel_Shared_ZipStreamWrapper { } /** - * 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 @@ class PHPExcel_Shared_ZipStreamWrapper { /** * EOF stream - * - * @return bool + * + * @return bool */ public function stream_eof() { return $this->_position >= strlen($this->_data); @@ -160,10 +160,10 @@ class PHPExcel_Shared_ZipStreamWrapper { /** * 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 b797d66..665e225 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 541e229..6a92297 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 @@ require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); */ 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'; + /** + * 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 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 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 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 '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 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() + /** + * 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); + /** + * 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() + $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() + /** + * 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 +} // 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 c6575a4..b60d5e7 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 @@ require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); */ 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'; + /** + * 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 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 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 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 '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() + /** + * 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() + /** + * 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 +} // 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 77e9ad2..c154466 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 @@ require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); */ 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'; + /** + * 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 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 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 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() + 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); + /** + * 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() + $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() + /** + * 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 +} // 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 5c9fec4..b43abe7 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 @@ require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/Matrix.php'; */ 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'; + /** + * 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; + /** + * 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 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 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 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 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() + $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() + /** + * 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() + 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); + /** + * 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; - } + $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->_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() + $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() + /** + * 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 +} // 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 5da232d..e4b229b 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 @@ require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'; */ 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'; + /** + * 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 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 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 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 '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() + /** + * 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); + /** + * 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() + $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() + /** + * 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 +} // 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 4ccb517..cbd5101 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 @@ require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/polynomialBestFitClass.php'; */ 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 77ad376..92868a4 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; - } + /** + * 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; + /** + * Set AutoFilter Parent Worksheet + * + * @param PHPExcel_Worksheet $pSheet + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setParent(PHPExcel_Worksheet $pSheet = NULL) { + $this->_workSheet = $pSheet; - return $this; - } + return $this; + } - /** - * Get AutoFilter Range - * - * @return string - */ - public function getRange() { - return $this->_range; - } + /** + * 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; - } + /** + * 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 (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]); - } - } - } + 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; - } + return $this; + } - /** - * Get all AutoFilter Columns - * - * @throws PHPExcel_Exception - * @return array of PHPExcel_Worksheet_AutoFilter_Column - */ - public function getColumns() { - return $this->_columns; - } + /** + * 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."); - } + /** + * 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."); - } + $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]; - } + 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 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); + /** + * 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); - } + if (!isset($this->_columns[$pColumn])) { + $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + } - return $this->_columns[$pColumn]; - } + 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); + /** + * 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); - } + 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); + /** + * 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); + 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; - } + 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); + /** + * 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]); - } + if (isset($this->_columns[$pColumn])) { + unset($this->_columns[$pColumn]); + } - return $this; - } + 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); + /** + * 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]); + 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; - } + 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 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; - } + /** + * 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; - } - } + 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; - } + 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; + /** + * 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; - } - } + 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; - } + 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; - } + /** + * 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; - } - } + if (is_numeric($cellValue)) { + $dateValue = date('m',PHPExcel_Shared_Date::ExcelToPHP($cellValue)); + if (in_array($dateValue,$monthSet)) { + return TRUE; + } + } - return FALSE; - } + 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('.*', '.', '~', '\*', '\?'); + /** + * 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; + /** + * 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; - } + $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) { + 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; - } + 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 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); + // 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 - ) - ); - } + 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) - ); + 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); - } + $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)); - } + 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); + /** + * 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); + // 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( + $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; + 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); + $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; - } - } + $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); +// 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); - } + // 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; - } + 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; - } - } - } + /** + * 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; - } + /** + * 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 e2ea1bb..577f8db 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'; + 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, - ); + /** + * 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'; + /* 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, - ); + /** + * 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 + * + * @var PHPExcel_Worksheet_AutoFilter + */ + private $_parent = NULL; - /** - * Autofilter Column Index - * - * @var string - */ - private $_columnIndex = ''; + /** + * Autofilter Column Index + * + * @var string + */ + private $_columnIndex = ''; - /** - * Autofilter Column Filter Type - * - * @var string - */ - private $_filterType = self::AUTOFILTER_FILTERTYPE_FILTER; + /** + * 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 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 Rules + * + * @var array of PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + private $_ruleset = array(); - /** - * Autofilter Column Dynamic Attributes - * - * @var array of mixed - */ - private $_attributes = 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; - } + /** + * 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; - } + /** + * 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); - } + /** + * 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; + $this->_columnIndex = $pColumn; - return $this; - } + return $this; + } - /** - * Get this Column's AutoFilter Parent - * - * @return PHPExcel_Worksheet_AutoFilter - */ - public function getParent() { - return $this->_parent; - } + /** + * 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; + /** + * 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; - } + return $this; + } - /** - * Get AutoFilter Type - * - * @return string - */ - public function getFilterType() { - return $this->_filterType; - } + /** + * 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.'); - } + /** + * 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; + $this->_filterType = $pFilterType; - return $this; - } + return $this; + } - /** - * Get AutoFilter Multiple Rules And/Or Join - * - * @return string - */ - public function getJoin() { - return $this->_join; - } + /** + * 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.'); - } + /** + * 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; + $this->_join = $pJoin; - return $this; - } + return $this; + } - /** - * Set AutoFilter Attributes - * - * @param string[] $pAttributes - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function setAttributes($pAttributes = array()) { - $this->_attributes = $pAttributes; + /** + * Set AutoFilter Attributes + * + * @param string[] $pAttributes + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setAttributes($pAttributes = array()) { + $this->_attributes = $pAttributes; - return $this; - } + 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; + /** + * 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; - } + return $this; + } - /** - * Get AutoFilter Column Attributes - * - * @return string - */ - public function getAttributes() { - return $this->_attributes; - } + /** + * 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 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 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]; - } + /** + * 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); + /** + * 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); - } + 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; + /** + * 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; - } + 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); - } - } + /** + * 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; - } + 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); + /** + * 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; - } + 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; - } - } - } + /** + * 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 eb9f71f..98c4630 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'; + 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, - ); + 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'; + 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, - ); + 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'; + 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, - ); + 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: - * - * - * - * - * - * - */ - 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'; + /* + * The only valid filter rule operators for filter and customFilter types are: + * + * + * + * + * + * + */ + 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, - ); + 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'; + 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, - ); + 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( - self::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP, - self::AUTOFILTER_COLUMN_RULE_TOPTEN_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'; // -// const AUTOFILTER_COLUMN_RULE_ALLDATESINMONTH = 'allDatesInMonth'; // for Month/February -// const AUTOFILTER_COLUMN_RULE_ALLDATESINQUARTER = 'allDatesInQuarter'; // for Quarter 2 + /* 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'; // +// const AUTOFILTER_COLUMN_RULE_ALLDATESINMONTH = 'allDatesInMonth'; // for Month/February +// const AUTOFILTER_COLUMN_RULE_ALLDATESINQUARTER = 'allDatesInQuarter'; // for Quarter 2 - /** - * Autofilter Column - * - * @var PHPExcel_Worksheet_AutoFilter_Column - */ - private $_parent = NULL; + /** + * Autofilter Column + * + * @var PHPExcel_Worksheet_AutoFilter_Column + */ + private $_parent = NULL; - /** - * Autofilter Rule Type - * - * @var string - */ - private $_ruleType = self::AUTOFILTER_RULETYPE_FILTER; + /** + * Autofilter Rule Type + * + * @var string + */ + private $_ruleType = self::AUTOFILTER_RULETYPE_FILTER; - /** - * Autofilter Rule Value - * - * @var string - */ - private $_value = ''; + /** + * Autofilter Rule Value + * + * @var string + */ + private $_value = ''; - /** - * Autofilter Rule Operator - * - * @var string - */ - private $_operator = self::AUTOFILTER_COLUMN_RULE_EQUAL; + /** + * Autofilter Rule Operator + * + * @var string + */ + private $_operator = self::AUTOFILTER_COLUMN_RULE_EQUAL; - /** - * DateTimeGrouping Group Value - * - * @var string - */ - private $_grouping = ''; + /** + * 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; - } + /** + * 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; - } + /** + * 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.'); - } + /** + * 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; + $this->_ruleType = $pRuleType; - return $this; - } + return $this; + } - /** - * Get AutoFilter Rule Value - * - * @return string - */ - public function getValue() { - return $this->_value; - } + /** + * 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; + /** + * 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; - } + return $this; + } - /** - * Get AutoFilter Rule Operator - * - * @return string - */ - public function getOperator() { - return $this->_operator; - } + /** + * 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; + /** + * 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; - } + return $this; + } - /** - * Get AutoFilter Rule Grouping - * - * @return string - */ - public function getGrouping() { - return $this->_grouping; - } + /** + * 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.'); - } + /** + * 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; + $this->_grouping = $pGrouping; - return $this; - } + 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); + /** + * 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; - } + return $this; + } - /** - * Get this Rule's AutoFilter Column Parent - * - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function getParent() { - return $this->_parent; - } + /** + * 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; + /** + * 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; - } + 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; - } - } - } + /** + * 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 e1d4715..d22c6b4 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 counter + * + * @var int + */ + private static $_imageCounter = 0; - /** - * Image index - * - * @var int - */ - private $_imageIndex = 0; + /** + * Image index + * + * @var int + */ + private $_imageIndex = 0; - /** - * Name - * - * @var string - */ - protected $_name; + /** + * Name + * + * @var string + */ + protected $_name; - /** - * Description - * - * @var string - */ - protected $_description; + /** + * Description + * + * @var string + */ + protected $_description; - /** - * Worksheet - * - * @var PHPExcel_Worksheet - */ - protected $_worksheet; + /** + * Worksheet + * + * @var PHPExcel_Worksheet + */ + protected $_worksheet; - /** - * Coordinates - * - * @var string - */ - protected $_coordinates; + /** + * Coordinates + * + * @var string + */ + protected $_coordinates; - /** - * Offset X - * - * @var int - */ - protected $_offsetX; + /** + * Offset X + * + * @var int + */ + protected $_offsetX; - /** - * Offset Y - * - * @var int - */ - protected $_offsetY; + /** + * Offset Y + * + * @var int + */ + protected $_offsetY; - /** - * Width - * - * @var int - */ - protected $_width; + /** + * Width + * + * @var int + */ + protected $_width; - /** - * Height - * - * @var int - */ - protected $_height; + /** + * Height + * + * @var int + */ + protected $_height; - /** - * Proportional resize - * - * @var boolean - */ - protected $_resizeProportional; + /** + * Proportional resize + * + * @var boolean + */ + protected $_resizeProportional; - /** - * Rotation - * - * @var int - */ - protected $_rotation; + /** + * Rotation + * + * @var int + */ + protected $_rotation; - /** - * Shadow - * - * @var PHPExcel_Worksheet_Drawing_Shadow - */ - protected $_shadow; + /** + * 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(); + // 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; + // Set image index + self::$_imageCounter++; + $this->_imageIndex = self::$_imageCounter; } /** @@ -155,7 +155,7 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return int */ public function getImageIndex() { - return $this->_imageIndex; + return $this->_imageIndex; } /** @@ -164,7 +164,7 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return string */ public function getName() { - return $this->_name; + return $this->_name; } /** @@ -174,8 +174,8 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return PHPExcel_Worksheet_BaseDrawing */ public function setName($pValue = '') { - $this->_name = $pValue; - return $this; + $this->_name = $pValue; + return $this; } /** @@ -184,7 +184,7 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return string */ public function getDescription() { - return $this->_description; + return $this->_description; } /** @@ -194,8 +194,8 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return PHPExcel_Worksheet_BaseDrawing */ public function setDescription($pValue = '') { - $this->_description = $pValue; - return $this; + $this->_description = $pValue; + return $this; } /** @@ -204,43 +204,43 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @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(); + 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; - } - } + 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; + // 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 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return string */ public function getCoordinates() { - return $this->_coordinates; + return $this->_coordinates; } /** @@ -259,8 +259,8 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return PHPExcel_Worksheet_BaseDrawing */ public function setCoordinates($pValue = 'A1') { - $this->_coordinates = $pValue; - return $this; + $this->_coordinates = $pValue; + return $this; } /** @@ -269,7 +269,7 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return int */ public function getOffsetX() { - return $this->_offsetX; + return $this->_offsetX; } /** @@ -279,8 +279,8 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return PHPExcel_Worksheet_BaseDrawing */ public function setOffsetX($pValue = 0) { - $this->_offsetX = $pValue; - return $this; + $this->_offsetX = $pValue; + return $this; } /** @@ -289,7 +289,7 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return int */ public function getOffsetY() { - return $this->_offsetY; + return $this->_offsetY; } /** @@ -299,8 +299,8 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return PHPExcel_Worksheet_BaseDrawing */ public function setOffsetY($pValue = 0) { - $this->_offsetY = $pValue; - return $this; + $this->_offsetY = $pValue; + return $this; } /** @@ -309,7 +309,7 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return int */ public function getWidth() { - return $this->_width; + return $this->_width; } /** @@ -319,16 +319,16 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @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 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return int */ public function getHeight() { - return $this->_height; + return $this->_height; } /** @@ -347,49 +347,49 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @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: - * - * $objDrawing->setResizeProportional(true); - * $objDrawing->setWidthAndHeight(160,120); - * - * + * Example: + * + * $objDrawing->setResizeProportional(true); + * $objDrawing->setWidthAndHeight(160,120); + * + * * @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 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return boolean */ public function getResizeProportional() { - return $this->_resizeProportional; + return $this->_resizeProportional; } /** @@ -407,8 +407,8 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return PHPExcel_Worksheet_BaseDrawing */ public function setResizeProportional($pValue = true) { - $this->_resizeProportional = $pValue; - return $this; + $this->_resizeProportional = $pValue; + return $this; } /** @@ -417,7 +417,7 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return int */ public function getRotation() { - return $this->_rotation; + return $this->_rotation; } /** @@ -427,8 +427,8 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @return PHPExcel_Worksheet_BaseDrawing */ public function setRotation($pValue = 0) { - $this->_rotation = $pValue; - return $this; + $this->_rotation = $pValue; + return $this; } /** @@ -437,53 +437,53 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * @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 956ffdc..05be76f 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 d58fceb..7f9dfd5 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 @@ class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implemen * @return string */ public function getFilename() { - return basename($this->_path); + return basename($this->_path); } /** @@ -69,9 +69,9 @@ class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implemen * @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 @@ class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implemen * @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 @@ class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implemen * @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 cc6289a..8776745 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 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @return boolean */ public function getVisible() { - return $this->_visible; + return $this->_visible; } /** @@ -129,8 +129,8 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setVisible($pValue = false) { - $this->_visible = $pValue; - return $this; + $this->_visible = $pValue; + return $this; } /** @@ -139,7 +139,7 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @return int */ public function getBlurRadius() { - return $this->_blurRadius; + return $this->_blurRadius; } /** @@ -149,8 +149,8 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setBlurRadius($pValue = 6) { - $this->_blurRadius = $pValue; - return $this; + $this->_blurRadius = $pValue; + return $this; } /** @@ -159,7 +159,7 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @return int */ public function getDistance() { - return $this->_distance; + return $this->_distance; } /** @@ -169,8 +169,8 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setDistance($pValue = 2) { - $this->_distance = $pValue; - return $this; + $this->_distance = $pValue; + return $this; } /** @@ -179,7 +179,7 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @return int */ public function getDirection() { - return $this->_direction; + return $this->_direction; } /** @@ -189,8 +189,8 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setDirection($pValue = 0) { - $this->_direction = $pValue; - return $this; + $this->_direction = $pValue; + return $this; } /** @@ -199,7 +199,7 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @return int */ public function getAlignment() { - return $this->_alignment; + return $this->_alignment; } /** @@ -209,8 +209,8 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setAlignment($pValue = 0) { - $this->_alignment = $pValue; - return $this; + $this->_alignment = $pValue; + return $this; } /** @@ -219,19 +219,19 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @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 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @return int */ public function getAlpha() { - return $this->_alpha; + return $this->_alpha; } /** @@ -250,39 +250,39 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * @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 6620682..3d2271a 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'; + /* 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 = ''; + /** + * OddHeader + * + * @var string + */ + private $_oddHeader = ''; - /** - * OddFooter - * - * @var string - */ - private $_oddFooter = ''; + /** + * OddFooter + * + * @var string + */ + private $_oddFooter = ''; - /** - * EvenHeader - * - * @var string - */ - private $_evenHeader = ''; + /** + * EvenHeader + * + * @var string + */ + private $_evenHeader = ''; - /** - * EvenFooter - * - * @var string - */ - private $_evenFooter = ''; + /** + * EvenFooter + * + * @var string + */ + private $_evenFooter = ''; - /** - * FirstHeader - * - * @var string - */ - private $_firstHeader = ''; + /** + * FirstHeader + * + * @var string + */ + private $_firstHeader = ''; - /** - * FirstFooter - * - * @var string - */ - private $_firstFooter = ''; + /** + * FirstFooter + * + * @var string + */ + private $_firstFooter = ''; - /** - * Different header for Odd/Even, defaults to false - * - * @var boolean - */ - private $_differentOddEven = false; + /** + * 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; + /** + * Different header for first page, defaults to false + * + * @var boolean + */ + private $_differentFirst = false; - /** - * Scale with document, defaults to true - * - * @var boolean - */ - private $_scaleWithDocument = true; + /** + * Scale with document, defaults to true + * + * @var boolean + */ + private $_scaleWithDocument = true; - /** - * Align with margins, defaults to true - * - * @var boolean - */ - private $_alignWithMargins = true; + /** + * Align with margins, defaults to true + * + * @var boolean + */ + private $_alignWithMargins = true; - /** - * Header/footer images - * - * @var PHPExcel_Worksheet_HeaderFooterDrawing[] - */ - private $_headerFooterImages = array(); + /** + * Header/footer images + * + * @var PHPExcel_Worksheet_HeaderFooterDrawing[] + */ + private $_headerFooterImages = array(); /** * Create a new PHPExcel_Worksheet_HeaderFooter @@ -193,7 +193,7 @@ class PHPExcel_Worksheet_HeaderFooter * @return string */ public function getOddHeader() { - return $this->_oddHeader; + return $this->_oddHeader; } /** @@ -203,8 +203,8 @@ class PHPExcel_Worksheet_HeaderFooter * @return PHPExcel_Worksheet_HeaderFooter */ public function setOddHeader($pValue) { - $this->_oddHeader = $pValue; - return $this; + $this->_oddHeader = $pValue; + return $this; } /** @@ -213,7 +213,7 @@ class PHPExcel_Worksheet_HeaderFooter * @return string */ public function getOddFooter() { - return $this->_oddFooter; + return $this->_oddFooter; } /** @@ -223,8 +223,8 @@ class PHPExcel_Worksheet_HeaderFooter * @return PHPExcel_Worksheet_HeaderFooter */ public function setOddFooter($pValue) { - $this->_oddFooter = $pValue; - return $this; + $this->_oddFooter = $pValue; + return $this; } /** @@ -233,7 +233,7 @@ class PHPExcel_Worksheet_HeaderFooter * @return string */ public function getEvenHeader() { - return $this->_evenHeader; + return $this->_evenHeader; } /** @@ -243,8 +243,8 @@ class PHPExcel_Worksheet_HeaderFooter * @return PHPExcel_Worksheet_HeaderFooter */ public function setEvenHeader($pValue) { - $this->_evenHeader = $pValue; - return $this; + $this->_evenHeader = $pValue; + return $this; } /** @@ -253,7 +253,7 @@ class PHPExcel_Worksheet_HeaderFooter * @return string */ public function getEvenFooter() { - return $this->_evenFooter; + return $this->_evenFooter; } /** @@ -263,8 +263,8 @@ class PHPExcel_Worksheet_HeaderFooter * @return PHPExcel_Worksheet_HeaderFooter */ public function setEvenFooter($pValue) { - $this->_evenFooter = $pValue; - return $this; + $this->_evenFooter = $pValue; + return $this; } /** @@ -273,7 +273,7 @@ class PHPExcel_Worksheet_HeaderFooter * @return string */ public function getFirstHeader() { - return $this->_firstHeader; + return $this->_firstHeader; } /** @@ -283,8 +283,8 @@ class PHPExcel_Worksheet_HeaderFooter * @return PHPExcel_Worksheet_HeaderFooter */ public function setFirstHeader($pValue) { - $this->_firstHeader = $pValue; - return $this; + $this->_firstHeader = $pValue; + return $this; } /** @@ -293,7 +293,7 @@ class PHPExcel_Worksheet_HeaderFooter * @return string */ public function getFirstFooter() { - return $this->_firstFooter; + return $this->_firstFooter; } /** @@ -303,8 +303,8 @@ class PHPExcel_Worksheet_HeaderFooter * @return PHPExcel_Worksheet_HeaderFooter */ public function setFirstFooter($pValue) { - $this->_firstFooter = $pValue; - return $this; + $this->_firstFooter = $pValue; + return $this; } /** @@ -313,7 +313,7 @@ class PHPExcel_Worksheet_HeaderFooter * @return boolean */ public function getDifferentOddEven() { - return $this->_differentOddEven; + return $this->_differentOddEven; } /** @@ -323,8 +323,8 @@ class PHPExcel_Worksheet_HeaderFooter * @return PHPExcel_Worksheet_HeaderFooter */ public function setDifferentOddEven($pValue = false) { - $this->_differentOddEven = $pValue; - return $this; + $this->_differentOddEven = $pValue; + return $this; } /** @@ -333,7 +333,7 @@ class PHPExcel_Worksheet_HeaderFooter * @return boolean */ public function getDifferentFirst() { - return $this->_differentFirst; + return $this->_differentFirst; } /** @@ -343,8 +343,8 @@ class PHPExcel_Worksheet_HeaderFooter * @return PHPExcel_Worksheet_HeaderFooter */ public function setDifferentFirst($pValue = false) { - $this->_differentFirst = $pValue; - return $this; + $this->_differentFirst = $pValue; + return $this; } /** @@ -353,7 +353,7 @@ class PHPExcel_Worksheet_HeaderFooter * @return boolean */ public function getScaleWithDocument() { - return $this->_scaleWithDocument; + return $this->_scaleWithDocument; } /** @@ -363,8 +363,8 @@ class PHPExcel_Worksheet_HeaderFooter * @return PHPExcel_Worksheet_HeaderFooter */ public function setScaleWithDocument($pValue = true) { - $this->_scaleWithDocument = $pValue; - return $this; + $this->_scaleWithDocument = $pValue; + return $this; } /** @@ -373,7 +373,7 @@ class PHPExcel_Worksheet_HeaderFooter * @return boolean */ public function getAlignWithMargins() { - return $this->_alignWithMargins; + return $this->_alignWithMargins; } /** @@ -383,8 +383,8 @@ class PHPExcel_Worksheet_HeaderFooter * @return PHPExcel_Worksheet_HeaderFooter */ public function setAlignWithMargins($pValue = true) { - $this->_alignWithMargins = $pValue; - return $this; + $this->_alignWithMargins = $pValue; + return $this; } /** @@ -396,8 +396,8 @@ class PHPExcel_Worksheet_HeaderFooter * @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 @@ class PHPExcel_Worksheet_HeaderFooter * @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 @@ class PHPExcel_Worksheet_HeaderFooter * @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 @@ class PHPExcel_Worksheet_HeaderFooter * @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; + // 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; + 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 99085b7..6468d4f 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; + /** + * Path + * + * @var string + */ + private $_path; - /** - * Name - * - * @var string - */ - protected $_name; + /** + * Name + * + * @var string + */ + protected $_name; - /** - * Offset X - * - * @var int - */ - protected $_offsetX; + /** + * Offset X + * + * @var int + */ + protected $_offsetX; - /** - * Offset Y - * - * @var int - */ - protected $_offsetY; + /** + * Offset Y + * + * @var int + */ + protected $_offsetY; - /** - * Width - * - * @var int - */ - protected $_width; + /** + * Width + * + * @var int + */ + protected $_width; - /** - * Height - * - * @var int - */ - protected $_height; + /** + * Height + * + * @var int + */ + protected $_height; - /** - * Proportional resize - * - * @var boolean - */ - protected $_resizeProportional; + /** + * 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 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @return string */ public function getName() { - return $this->_name; + return $this->_name; } /** @@ -115,8 +115,8 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @return PHPExcel_Worksheet_HeaderFooterDrawing */ public function setName($pValue = '') { - $this->_name = $pValue; - return $this; + $this->_name = $pValue; + return $this; } /** @@ -125,7 +125,7 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @return int */ public function getOffsetX() { - return $this->_offsetX; + return $this->_offsetX; } /** @@ -135,8 +135,8 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @return PHPExcel_Worksheet_HeaderFooterDrawing */ public function setOffsetX($pValue = 0) { - $this->_offsetX = $pValue; - return $this; + $this->_offsetX = $pValue; + return $this; } /** @@ -145,7 +145,7 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @return int */ public function getOffsetY() { - return $this->_offsetY; + return $this->_offsetY; } /** @@ -155,8 +155,8 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @return PHPExcel_Worksheet_HeaderFooterDrawing */ public function setOffsetY($pValue = 0) { - $this->_offsetY = $pValue; - return $this; + $this->_offsetY = $pValue; + return $this; } /** @@ -165,7 +165,7 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @return int */ public function getWidth() { - return $this->_width; + return $this->_width; } /** @@ -175,16 +175,16 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @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 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @return int */ public function getHeight() { - return $this->_height; + return $this->_height; } /** @@ -203,45 +203,45 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @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: - * + * Example: + * * $objDrawing->setResizeProportional(true); * $objDrawing->setWidthAndHeight(160,120); - * - * + * + * * @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 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @return boolean */ public function getResizeProportional() { - return $this->_resizeProportional; + return $this->_resizeProportional; } /** @@ -259,8 +259,8 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @return PHPExcel_Worksheet_HeaderFooterDrawing */ public function setResizeProportional($pValue = true) { - $this->_resizeProportional = $pValue; - return $this; + $this->_resizeProportional = $pValue; + return $this; } /** @@ -269,7 +269,7 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @return string */ public function getFilename() { - return basename($this->_path); + return basename($this->_path); } /** @@ -288,63 +288,63 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * @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 ($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 - . $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 b6c71af..86fc681 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'; + /* 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'; + /* 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; + /** + * Image resource + * + * @var resource + */ + private $_imageResource; - /** - * Rendering function - * - * @var string - */ - private $_renderingFunction; + /** + * Rendering function + * + * @var string + */ + private $_renderingFunction; - /** - * Mime type - * - * @var string - */ - private $_mimeType; + /** + * Mime type + * + * @var string + */ + private $_mimeType; - /** - * Unique name - * - * @var string - */ - private $_uniqueName; + /** + * 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)); + // 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(); + // Initialize parent + parent::__construct(); } /** @@ -96,24 +96,24 @@ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing im * @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; + $this->_imageResource = $value; - if (!is_null($this->_imageResource)) { - // Get width/height - $this->_width = imagesx($this->_imageResource); - $this->_height = imagesy($this->_imageResource); - } - return $this; + if (!is_null($this->_imageResource)) { + // Get width/height + $this->_width = imagesx($this->_imageResource); + $this->_height = imagesy($this->_imageResource); + } + return $this; } /** @@ -122,7 +122,7 @@ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing im * @return string */ public function getRenderingFunction() { - return $this->_renderingFunction; + return $this->_renderingFunction; } /** @@ -132,8 +132,8 @@ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing im * @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 @@ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing im * @return string */ public function getMimeType() { - return $this->_mimeType; + return $this->_mimeType; } /** @@ -152,8 +152,8 @@ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing im * @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 @@ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing im * @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 3b83afb..38cbce6 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; + /** + * Left + * + * @var double + */ + private $_left = 0.7; - /** - * Right - * - * @var double - */ - private $_right = 0.7; + /** + * Right + * + * @var double + */ + private $_right = 0.7; - /** - * Top - * - * @var double - */ - private $_top = 0.75; + /** + * Top + * + * @var double + */ + private $_top = 0.75; - /** - * Bottom - * - * @var double - */ - private $_bottom = 0.75; + /** + * Bottom + * + * @var double + */ + private $_bottom = 0.75; - /** - * Header - * - * @var double - */ - private $_header = 0.3; + /** + * Header + * + * @var double + */ + private $_header = 0.3; - /** - * Footer - * - * @var double - */ - private $_footer = 0.3; + /** + * Footer + * + * @var double + */ + private $_footer = 0.3; /** * Create a new PHPExcel_Worksheet_PageMargins @@ -90,7 +90,7 @@ class PHPExcel_Worksheet_PageMargins * @return double */ public function getLeft() { - return $this->_left; + return $this->_left; } /** @@ -100,8 +100,8 @@ class PHPExcel_Worksheet_PageMargins * @return PHPExcel_Worksheet_PageMargins */ public function setLeft($pValue) { - $this->_left = $pValue; - return $this; + $this->_left = $pValue; + return $this; } /** @@ -110,7 +110,7 @@ class PHPExcel_Worksheet_PageMargins * @return double */ public function getRight() { - return $this->_right; + return $this->_right; } /** @@ -120,8 +120,8 @@ class PHPExcel_Worksheet_PageMargins * @return PHPExcel_Worksheet_PageMargins */ public function setRight($pValue) { - $this->_right = $pValue; - return $this; + $this->_right = $pValue; + return $this; } /** @@ -130,7 +130,7 @@ class PHPExcel_Worksheet_PageMargins * @return double */ public function getTop() { - return $this->_top; + return $this->_top; } /** @@ -140,8 +140,8 @@ class PHPExcel_Worksheet_PageMargins * @return PHPExcel_Worksheet_PageMargins */ public function setTop($pValue) { - $this->_top = $pValue; - return $this; + $this->_top = $pValue; + return $this; } /** @@ -150,7 +150,7 @@ class PHPExcel_Worksheet_PageMargins * @return double */ public function getBottom() { - return $this->_bottom; + return $this->_bottom; } /** @@ -160,8 +160,8 @@ class PHPExcel_Worksheet_PageMargins * @return PHPExcel_Worksheet_PageMargins */ public function setBottom($pValue) { - $this->_bottom = $pValue; - return $this; + $this->_bottom = $pValue; + return $this; } /** @@ -170,7 +170,7 @@ class PHPExcel_Worksheet_PageMargins * @return double */ public function getHeader() { - return $this->_header; + return $this->_header; } /** @@ -180,8 +180,8 @@ class PHPExcel_Worksheet_PageMargins * @return PHPExcel_Worksheet_PageMargins */ public function setHeader($pValue) { - $this->_header = $pValue; - return $this; + $this->_header = $pValue; + return $this; } /** @@ -190,7 +190,7 @@ class PHPExcel_Worksheet_PageMargins * @return double */ public function getFooter() { - return $this->_footer; + return $this->_footer; } /** @@ -200,21 +200,21 @@ class PHPExcel_Worksheet_PageMargins * @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 86af283..2070cf9 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; + /* 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'; + /* 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'; + /* Print Range Set Method */ + const SETPRINTRANGE_OVERWRITE = 'O'; + const SETPRINTRANGE_INSERT = 'I'; - /** - * Paper size - * - * @var int - */ - private $_paperSize = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER; + /** + * Paper size + * + * @var int + */ + private $_paperSize = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER; - /** - * Orientation - * - * @var string - */ - private $_orientation = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT; + /** + * 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; + /** + * 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 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 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; + /** + * 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('', ''); + /** + * 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); + /** + * 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 horizontally + * + * @var boolean + */ + private $_horizontalCentered = FALSE; - /** - * Center page vertically - * - * @var boolean - */ - private $_verticalCentered = FALSE; + /** + * Center page vertically + * + * @var boolean + */ + private $_verticalCentered = FALSE; - /** - * Print area - * - * @var string - */ - private $_printArea = NULL; + /** + * Print area + * + * @var string + */ + private $_printArea = NULL; - /** - * First page number - * - * @var int - */ - private $_firstPageNumber = NULL; + /** + * First page number + * + * @var int + */ + private $_firstPageNumber = NULL; /** * Create a new PHPExcel_Worksheet_PageSetup @@ -287,7 +287,7 @@ class PHPExcel_Worksheet_PageSetup * @return int */ public function getPaperSize() { - return $this->_paperSize; + return $this->_paperSize; } /** @@ -297,8 +297,8 @@ class PHPExcel_Worksheet_PageSetup * @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 @@ class PHPExcel_Worksheet_PageSetup * @return string */ public function getOrientation() { - return $this->_orientation; + return $this->_orientation; } /** @@ -317,449 +317,449 @@ class PHPExcel_Worksheet_PageSetup * @return PHPExcel_Worksheet_PageSetup */ public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) { - $this->_orientation = $pValue; - return $this; + $this->_orientation = $pValue; + return $this; } - /** - * Get Scale - * - * @return int? - */ - public function getScale() { - return $this->_scale; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } - } + /** + * 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; - } + 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; - } + /** + * 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 + * + * @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; - } + /** + * 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; - } - } + /** + * 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; - } + 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; - } + /** + * 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 + * + * @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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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"); - } + /** + * 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]); - } + /** + * 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); - } - } + /** + * 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; - } + 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 all 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); + /** + * 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 all 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.'); - } + 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; - } + 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); - } + /** + * 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 all 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 - */ + /** + * 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 all 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); + 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 - */ + /** + * 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); - } + return $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, self::SETPRINTRANGE_INSERT); + } - /** - * Get first page number - * - * @return int - */ + /** + * Get first page number + * + * @return int + */ public function getFirstPageNumber() { - return $this->_firstPageNumber; + return $this->_firstPageNumber; } /** @@ -769,8 +769,8 @@ class PHPExcel_Worksheet_PageSetup * @return PHPExcel_Worksheet_HeaderFooter */ public function setFirstPageNumber($value = null) { - $this->_firstPageNumber = $value; - return $this; + $this->_firstPageNumber = $value; + return $this; } /** @@ -779,20 +779,20 @@ class PHPExcel_Worksheet_PageSetup * @return PHPExcel_Worksheet_HeaderFooter */ public function resetFirstPageNumber() { - return $this->setFirstPageNumber(null); + 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; - } - } - } + /** + * 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 1290a91..af34198 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; + /** + * Sheet + * + * @var boolean + */ + private $_sheet = false; - /** - * Objects - * - * @var boolean - */ - private $_objects = false; + /** + * Objects + * + * @var boolean + */ + private $_objects = false; - /** - * Scenarios - * - * @var boolean - */ - private $_scenarios = false; + /** + * Scenarios + * + * @var boolean + */ + private $_scenarios = false; - /** - * Format cells - * - * @var boolean - */ - private $_formatCells = false; + /** + * Format cells + * + * @var boolean + */ + private $_formatCells = false; - /** - * Format columns - * - * @var boolean - */ - private $_formatColumns = false; + /** + * Format columns + * + * @var boolean + */ + private $_formatColumns = false; - /** - * Format rows - * - * @var boolean - */ - private $_formatRows = false; + /** + * Format rows + * + * @var boolean + */ + private $_formatRows = false; - /** - * Insert columns - * - * @var boolean - */ - private $_insertColumns = false; + /** + * Insert columns + * + * @var boolean + */ + private $_insertColumns = false; - /** - * Insert rows - * - * @var boolean - */ - private $_insertRows = false; + /** + * Insert rows + * + * @var boolean + */ + private $_insertRows = false; - /** - * Insert hyperlinks - * - * @var boolean - */ - private $_insertHyperlinks = false; + /** + * Insert hyperlinks + * + * @var boolean + */ + private $_insertHyperlinks = false; - /** - * Delete columns - * - * @var boolean - */ - private $_deleteColumns = false; + /** + * Delete columns + * + * @var boolean + */ + private $_deleteColumns = false; - /** - * Delete rows - * - * @var boolean - */ - private $_deleteRows = false; + /** + * Delete rows + * + * @var boolean + */ + private $_deleteRows = false; - /** - * Select locked cells - * - * @var boolean - */ - private $_selectLockedCells = false; + /** + * Select locked cells + * + * @var boolean + */ + private $_selectLockedCells = false; - /** - * Sort - * - * @var boolean - */ - private $_sort = false; + /** + * Sort + * + * @var boolean + */ + private $_sort = false; - /** - * AutoFilter - * - * @var boolean - */ - private $_autoFilter = false; + /** + * AutoFilter + * + * @var boolean + */ + private $_autoFilter = false; - /** - * Pivot tables - * - * @var boolean - */ - private $_pivotTables = false; + /** + * Pivot tables + * + * @var boolean + */ + private $_pivotTables = false; - /** - * Select unlocked cells - * - * @var boolean - */ - private $_selectUnlockedCells = false; + /** + * Select unlocked cells + * + * @var boolean + */ + private $_selectUnlockedCells = false; - /** - * Password - * - * @var string - */ - private $_password = ''; + /** + * Password + * + * @var string + */ + private $_password = ''; /** * Create a new PHPExcel_Worksheet_Protection @@ -167,22 +167,22 @@ class PHPExcel_Worksheet_Protection * @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 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getSheet() { - return $this->_sheet; + return $this->_sheet; } /** @@ -201,8 +201,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setSheet($pValue = false) { - $this->_sheet = $pValue; - return $this; + $this->_sheet = $pValue; + return $this; } /** @@ -211,7 +211,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getObjects() { - return $this->_objects; + return $this->_objects; } /** @@ -221,8 +221,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setObjects($pValue = false) { - $this->_objects = $pValue; - return $this; + $this->_objects = $pValue; + return $this; } /** @@ -231,7 +231,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getScenarios() { - return $this->_scenarios; + return $this->_scenarios; } /** @@ -241,8 +241,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setScenarios($pValue = false) { - $this->_scenarios = $pValue; - return $this; + $this->_scenarios = $pValue; + return $this; } /** @@ -251,7 +251,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getFormatCells() { - return $this->_formatCells; + return $this->_formatCells; } /** @@ -261,8 +261,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setFormatCells($pValue = false) { - $this->_formatCells = $pValue; - return $this; + $this->_formatCells = $pValue; + return $this; } /** @@ -271,7 +271,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getFormatColumns() { - return $this->_formatColumns; + return $this->_formatColumns; } /** @@ -281,8 +281,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setFormatColumns($pValue = false) { - $this->_formatColumns = $pValue; - return $this; + $this->_formatColumns = $pValue; + return $this; } /** @@ -291,7 +291,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getFormatRows() { - return $this->_formatRows; + return $this->_formatRows; } /** @@ -301,8 +301,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setFormatRows($pValue = false) { - $this->_formatRows = $pValue; - return $this; + $this->_formatRows = $pValue; + return $this; } /** @@ -311,7 +311,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getInsertColumns() { - return $this->_insertColumns; + return $this->_insertColumns; } /** @@ -321,8 +321,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setInsertColumns($pValue = false) { - $this->_insertColumns = $pValue; - return $this; + $this->_insertColumns = $pValue; + return $this; } /** @@ -331,7 +331,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getInsertRows() { - return $this->_insertRows; + return $this->_insertRows; } /** @@ -341,8 +341,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setInsertRows($pValue = false) { - $this->_insertRows = $pValue; - return $this; + $this->_insertRows = $pValue; + return $this; } /** @@ -351,7 +351,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getInsertHyperlinks() { - return $this->_insertHyperlinks; + return $this->_insertHyperlinks; } /** @@ -361,8 +361,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setInsertHyperlinks($pValue = false) { - $this->_insertHyperlinks = $pValue; - return $this; + $this->_insertHyperlinks = $pValue; + return $this; } /** @@ -371,7 +371,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getDeleteColumns() { - return $this->_deleteColumns; + return $this->_deleteColumns; } /** @@ -381,8 +381,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setDeleteColumns($pValue = false) { - $this->_deleteColumns = $pValue; - return $this; + $this->_deleteColumns = $pValue; + return $this; } /** @@ -391,7 +391,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getDeleteRows() { - return $this->_deleteRows; + return $this->_deleteRows; } /** @@ -401,8 +401,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setDeleteRows($pValue = false) { - $this->_deleteRows = $pValue; - return $this; + $this->_deleteRows = $pValue; + return $this; } /** @@ -411,7 +411,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getSelectLockedCells() { - return $this->_selectLockedCells; + return $this->_selectLockedCells; } /** @@ -421,8 +421,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setSelectLockedCells($pValue = false) { - $this->_selectLockedCells = $pValue; - return $this; + $this->_selectLockedCells = $pValue; + return $this; } /** @@ -431,7 +431,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getSort() { - return $this->_sort; + return $this->_sort; } /** @@ -441,8 +441,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setSort($pValue = false) { - $this->_sort = $pValue; - return $this; + $this->_sort = $pValue; + return $this; } /** @@ -451,7 +451,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getAutoFilter() { - return $this->_autoFilter; + return $this->_autoFilter; } /** @@ -461,8 +461,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setAutoFilter($pValue = false) { - $this->_autoFilter = $pValue; - return $this; + $this->_autoFilter = $pValue; + return $this; } /** @@ -471,7 +471,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getPivotTables() { - return $this->_pivotTables; + return $this->_pivotTables; } /** @@ -481,8 +481,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setPivotTables($pValue = false) { - $this->_pivotTables = $pValue; - return $this; + $this->_pivotTables = $pValue; + return $this; } /** @@ -491,7 +491,7 @@ class PHPExcel_Worksheet_Protection * @return boolean */ function getSelectUnlockedCells() { - return $this->_selectUnlockedCells; + return $this->_selectUnlockedCells; } /** @@ -501,8 +501,8 @@ class PHPExcel_Worksheet_Protection * @return PHPExcel_Worksheet_Protection */ function setSelectUnlockedCells($pValue = false) { - $this->_selectUnlockedCells = $pValue; - return $this; + $this->_selectUnlockedCells = $pValue; + return $this; } /** @@ -511,35 +511,35 @@ class PHPExcel_Worksheet_Protection * @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; + 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; - } - } - } + /** + * 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 2396dda..f2448e2 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'; + /* 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, - ); + 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; + /** + * 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; + /** + * 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; + /** + * 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 @@ class PHPExcel_Worksheet_SheetView { } - /** - * Get ZoomScale - * - * @return int - */ - public function getZoomScale() { - return $this->_zoomScale; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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; - } + /** + * 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."); - } + /** + * 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; - } + 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/Writer/Excel2007/WriterPart.php b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php index 1ade577..a25ecd6 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 c85e36a..f1e98a1 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 1f6ddc4..2e1986a 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 da7faa0..a280b88 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": "*",