From c9daa12245a375469916dfba86e3f491e922e321 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Aug 2012 22:11:26 +0100 Subject: [PATCH] Initial work on AutoFilter selections reading from Excel2007 (with diagnostics, remember to remove before any merging to develop) --- Classes/PHPExcel/Reader/Excel2007.php | 24 +- Classes/PHPExcel/Worksheet.php | 8 +- Classes/PHPExcel/Worksheet/AutoFilter.php | 184 ++++++++++- .../PHPExcel/Worksheet/AutoFilter/Column.php | 301 ++++++++++++++++++ .../Worksheet/AutoFilter/Column/Rule.php | 209 ++++++++++++ .../Worksheet/AutoFilter/ColumnTest.php | 45 +++ .../PHPExcel/Worksheet/AutoFilterTest.php | 294 +++++++++++++++++ 7 files changed, 1055 insertions(+), 10 deletions(-) create mode 100644 Classes/PHPExcel/Worksheet/AutoFilter/Column.php create mode 100644 Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php create mode 100644 unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php create mode 100644 unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 73af9033..743f9264 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1098,7 +1098,29 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader } if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) { - $docSheet->getAutoFilter()->setRange((string) $xmlSheet->autoFilter["ref"]); + $autoFilter = $docSheet->getAutoFilter(); + $autoFilter->setRange((string) $xmlSheet->autoFilter["ref"]); + foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { + $column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]); + if ($filterColumn->filters) { + $filters = $filterColumn->filters; + foreach ($filters->filter as $filterRule) { + echo 'FILTER RULE',PHP_EOL; + echo (string) $filterRule["val"],PHP_EOL; + echo (string) $filterRule["operator"],PHP_EOL; + } + } + if ($filterColumn->customFilters) { + $customFilters = $filterColumn->customFilters; + echo (string) $customFilters["and"],PHP_EOL; + foreach ($customFilters->customFilter as $customFilterRule) { + echo 'CUSTOM FILTER RULE',PHP_EOL; + echo (string) $customFilterRule["val"],PHP_EOL; + echo (string) $customFilterRule["operator"],PHP_EOL; + } + } + } + var_dump($autoFilter); } if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) { diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index d2d96360..64256dc1 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -362,12 +362,12 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable $this->_protection = new PHPExcel_Worksheet_Protection(); // Default row dimension - $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(null); + $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(NULL); // Default column dimension - $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(null); + $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(NULL); - $this->_autoFilter = new PHPExcel_Worksheet_AutoFilter(); + $this->_autoFilter = new PHPExcel_Worksheet_AutoFilter(NULL, $this); } @@ -1883,7 +1883,7 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable */ public function removeAutoFilter() { - $this->_autoFilter = ''; + $this->_autoFilter->setRange(NULL); return $this; } diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index c0055a5b..6620ddec 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -35,6 +35,14 @@ */ class PHPExcel_Worksheet_AutoFilter { + /** + * Autofilter Worksheet + * + * @var PHPExcel_Worksheet + */ + private $_workSheet = NULL; + + /** * Autofilter Range * @@ -43,14 +51,44 @@ class PHPExcel_Worksheet_AutoFilter private $_range = ''; + /** + * Autofilter Column Ruleset + * + * @var array of PHPExcel_Worksheet_AutoFilter_Column + */ + private $_columns = array(); + + /** * Create a new PHPExcel_Worksheet_AutoFilter */ - public function __construct($pRange = '') + public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = NULL) { $this->_range = $pRange; + $this->_workSheet = $pSheet; } + /** + * Get AutoFilter Parent Worksheet + * + * @return PHPExcel_Worksheet + */ + public function getParent() { + return $this->_workSheet; + } + + /** + * Set AutoFilter Parent Worksheet + * + * @param PHPExcel_Worksheet + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setParent(PHPExcel_Worksheet $pSheet = NULL) { + $this->_workSheet = $pSheet; + + return $this; + } + /** * Get AutoFilter Range * @@ -64,19 +102,142 @@ class PHPExcel_Worksheet_AutoFilter * Set AutoFilter Range * * @param string $pRange Cell range (i.e. A1:E10) - * @throws Exception + * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter */ public function setRange($pRange = '') { // Uppercase coordinate - $pRange = strtoupper($pRange); + $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 Exception('Autofilter must be set on a range of cells.'); + throw new PHPExcel_Exception('Autofilter must be set on a range of cells.'); + } + + if (empty($pRange)) { + // Discard all column rules + $this->_columns = array(); + } else { + // Discard any column rules that are no longer valid within this range + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + foreach($this->_columns as $key => $value) { + $colIndex = PHPExcel_Cell::columnIndexFromString($key); + if (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) { + unset($this->_columns[$key]); + } + } + } + + return $this; + } + + /** + * Get all AutoFilter Columns + * + * @throws PHPExcel_Exception + * @return array of PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumns() { + return $this->_columns; + } + + /** + * Validate that the specified column is in the AutoFilter range + * + * @param string $column Column name (e.g. A) + * @throws PHPExcel_Exception + * @return integer The column offset within the autofilter range + */ + protected function _testColumnInRange($column) { + if (empty($this->_range)) { + throw new PHPExcel_Exception("No autofilter range is defined."); + } + + $columnIndex = PHPExcel_Cell::columnIndexFromString($column); + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) { + throw new PHPExcel_Exception("Column is outside of current autofilter range."); + } + + return $columnIndex - $rangeStart[0]; + } + + /** + * Get a specified AutoFilter Column Offset within the defined AutoFilter range + * + * @param string $pColumn Column name (e.g. A) + * @throws PHPExcel_Exception + * @return integer The offset of the specified column within the autofilter range + */ + public function getColumnOffset($pColumn) { + return $this->_testColumnInRange($pColumn); + } + + /** + * Get a specified AutoFilter Column + * + * @param string $pColumn Column name (e.g. A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumn($pColumn) { + $this->_testColumnInRange($pColumn); + + if (!isset($this->_columns[$pColumn])) { + $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + } + return $this->_columns[$pColumn]; + } + + /** + * Get a specified AutoFilter Column by it's offset + * + * @param integer $pColumnOffset Column offset within range (starting from 0) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumnByOffset($pColumnOffset = 0) { + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + $pColumn = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1); + + echo 'Filter rules to apply for column ',$pColumn,PHP_EOL; + + if (!isset($this->_columns[$pColumn])) { + $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + } + return $this->_columns[$pColumn]; + } + + /** + * Set AutoFilter + * + * @param PHPExcel_Worksheet_AutoFilter_Column|string $pColumn + * A simple string containing a Column ID like 'A' is permitted + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setColumn($pColumn) + { + if ((is_string($pColumn)) && (!empty($pColumn))) { + $column = $pColumn; + } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { + $column = $pColumn->getColumnIndex(); + } else { + throw new PHPExcel_Exception("Column is not within the autofilter range."); + } + $this->_testColumnInRange($column); + + if (is_string($pColumn)) { + $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { + $pColumn->setParent($this); + $this->_columns[$column] = $pColumn; } return $this; @@ -89,7 +250,20 @@ class PHPExcel_Worksheet_AutoFilter $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { - $this->$key = clone $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; + // attache the new cloned Column to this new cloned Autofilter object + $this->$key[$k]->setParent($this); + } } else { $this->$key = $value; } diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php new file mode 100644 index 00000000..33ca3e0a --- /dev/null +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php @@ -0,0 +1,301 @@ +_columnIndex = $pColumn; + $this->_parent = $pParent; + } + + /** + * Get AutoFilter Column Index + * + * @return string + */ + public function getColumnIndex() { + return $this->_columnIndex; + } + + /** + * Set AutoFilter Column Index + * + * @param string $pColumn Column (e.g. A) + * @throws Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setColumnIndex($pColumn) { + // Uppercase coordinate + $pColumn = strtoupper($pColumn); + if ($this->_parent !== NULL) { + $this->_parent->_testColumnInRange($pColumn); + } + + $this->_columnIndex = $pColumn; + + return $this; + } + + /** + * Get this Column's AutoFilter Parent + * + * @return PHPExcel_Worksheet_AutoFilter + */ + public function getParent() { + return $this->_parent; + } + + /** + * Set this Column's AutoFilter Parent + * + * @param PHPExcel_Worksheet_AutoFilter + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setParent(PHPExcel_Worksheet_AutoFilter $pParent = NULL) { + $this->_parent = $pParent; + + return $this; + } + + /** + * Get AutoFilter Multiple Rules And/Or + * + * @return string + */ + public function getAndOr() { + return $this->_andOr; + } + + /** + * Set AutoFilter Multiple Rules And/Or + * + * @param string $pAndOr And/Or + * @throws Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setAndOr($pAndOr = self::AUTOFILTER_COLUMN_ANDOR_OR) { + // Lowercase And/Or + $pAndOr = strtolower($pAndOr); + if (!in_array($pDataType,self::$_ruleConnections)) { + throw new PHPExcel_Exception('Invalid rule connection for column AutoFilter.'); + } + + $this->_andOr = $pAndOr; + + return $this; + } + + /** + * Get AutoFilter Column Data Type + * + * @return string + */ + public function getDataType() { + if ($this->_dataType === NULL) { + } + + return $this->_dataType; + } + + /** + * Set AutoFilter Column Data Type + * + * @param string $pDataType Data Type + * @throws Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setDataType($pDataType = self::AUTOFILTER_COLUMN_DATATYPE_STRING) { + // Lowercase datatype + $pDataType = strtolower($pDataType); + if (!in_array($pDataType,self::$_dataTypes)) { + throw new PHPExcel_Exception('Invalid datatype for column AutoFilter.'); + } + + $this->_dataType = $pDataType; + + return $this; + } + + /** + * Get all AutoFilter Column Rules + * + * @throws PHPExcel_Exception + * @return array of PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function getRules() { + return $this->_ruleset; + } + + /** + * Get a specified AutoFilter Column Rule + * + * @param integer $pIndex Rule index in the ruleset array + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function getRule($pIndex) { + if (!isset($this->_ruleset[$pIndex])) { + $this->_ruleset[$pIndex] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); + } + return $this->_ruleset[$pIndex]; + } + + /** + * Create a new AutoFilter Column Rule in the ruleset + * + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function createRule() { + $this->_ruleset[] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); + + return end($this->_ruleset); + } + + /** + * Add a new AutoFilter Column Rule to the ruleset + * + * @param PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule + * @param boolean $returnRule Flag indicating whether the rule object or the column object should be returned + * @return PHPExcel_Worksheet_AutoFilter_Column|PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $returnRule=TRUE) { + $pRule->setParent($this); + $this->_ruleset[] = $pRule; + + return ($returnRule) ? $pRule : $this; + } + + /** + * Delete a specified AutoFilter Column Rule + * + * @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]); + } + 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; + } + } else { + $this->$key = $value; + } + } + } + +} diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php new file mode 100644 index 00000000..fa0e01dc --- /dev/null +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php @@ -0,0 +1,209 @@ + + const AUTOFILTER_COLUMN_RULE_ALLDATESINMONTH = 'allDatesInMonth'; // for Month/February + const AUTOFILTER_COLUMN_RULE_ALLDATESINQUARTER = 'allDatesInQuarter'; // for Quarter 2 + /* 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* + + /** + * Autofilter Column + * + * @var PHPExcel_Worksheet_AutoFilter_Column + */ + private $_parent = NULL; + + + /** + * Autofilter Rule Value + * + * @var string + */ + private $_ruleValue = ''; + + /** + * Autofilter Rule Operator + * + * @var string + */ + private $_ruleOperator = ''; + + + /** + * Create a new PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) + { + $this->_parent = $pParent; + } + + /** + * Get AutoFilter Rule Value + * + * @return string + */ + public function getValue() { + return $this->_value; + } + + /** + * Set AutoFilter Rule Value + * + * @param string $pValue + * @throws Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setValue($pValue = '') { + $this->_value = $pValue; + + return $this; + } + + /** + * Get AutoFilter Rule Operator + * + * @return string + */ + public function getOperator() { + return $this->_operator; + } + + /** + * Set AutoFilter Rule Operator + * + * @param string $pOperator + * @throws Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) { + $this->_operator = $pOperator; + + return $this; + } + + /** + * Set AutoFilter Rule Operator + * + * @param string $pOperator + * @throws Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setRule($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL, $pValue = '' { + $this->setOperator($pOperator); + $this->setValue($pValue); + + return $this; + } + + /** + * Get this Rule's AutoFilter Column Parent + * + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getParent() { + return $this->_parent; + } + + /** + * Set this Rule's AutoFilter Column Parent + * + * @param PHPExcel_Worksheet_AutoFilter_Column + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setParent(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) { + $this->_parent = $pParent; + + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + if ($key == '_parent') { + // Detach from autofilter column parent + $this->$key = NULL; + } else { + $this->$key = clone $value; + } + } else { + $this->$key = $value; + } + } + } + +} diff --git a/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php new file mode 100644 index 00000000..db7729c9 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php @@ -0,0 +1,45 @@ +_testAutoFilterColumnObject = new PHPExcel_Worksheet_AutoFilter_Column($this->_testInitialColumn); + } + + public function testGetColumnIndex() + { + $result = $this->_testAutoFilterColumnObject->getColumnIndex(); + $this->assertEquals($this->_testInitialColumn, $result); + } + + public function testSetColumnIndex() + { + $expectedResult = 'L'; + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterColumnObject->setColumnIndex($expectedResult); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + + $result = $this->_testAutoFilterColumnObject->getColumnIndex(); + $this->assertEquals($expectedResult, $result); + } + + public function testClone() + { + $result = clone $this->_testAutoFilterColumnObject; + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + } + +} diff --git a/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php b/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php new file mode 100644 index 00000000..650880f0 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php @@ -0,0 +1,294 @@ +_testAutoFilterObject = new PHPExcel_Worksheet_AutoFilter($this->_testInitialRange); + } + + public function testToString() + { + $expectedResult = $this->_testInitialRange; + + // magic __toString should return the active autofilter range + $result = $this->_testAutoFilterObject; + $this->assertEquals($expectedResult, $result); + } + + public function testGetRange() + { + $expectedResult = $this->_testInitialRange; + + // Result should be the active autofilter range + $result = $this->_testAutoFilterObject->getRange(); + $this->assertEquals($expectedResult, $result); + } + + public function testSetRange() + { + $expectedResult = 'G1:J512'; + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setRange($expectedResult); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + // Result should be the new autofilter range + $result = $this->_testAutoFilterObject->getRange(); + $this->assertEquals($expectedResult, $result); + } + + public function testClearRange() + { + $expectedResult = ''; + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setRange(); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + // Result should be a clear range + $result = $this->_testAutoFilterObject->getRange(); + $this->assertEquals($expectedResult, $result); + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testSetRangeInvalidRange() + { + $expectedResult = 'A1'; + + $result = $this->_testAutoFilterObject->setRange($expectedResult); + } + + public function testGetColumnsEmpty() + { + // There should be no columns yet defined + $result = $this->_testAutoFilterObject->getColumns(); + $this->assertInternalType('array', $result); + $this->assertEquals(0, count($result)); + } + + public function testGetColumnOffset() + { + $columnIndexes = array( 'H' => 0, + 'K' => 3, + 'M' => 5 + ); + + // If we request a specific column by its column ID, we should get an + // integer returned representing the column offset within the range + foreach($columnIndexes as $columnIndex => $columnOffset) { + $result = $this->_testAutoFilterObject->getColumnOffset($columnIndex); + $this->assertEquals($columnOffset, $result); + } + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testGetInvalidColumnOffset() + { + $invalidColumn = 'G'; + + $result = $this->_testAutoFilterObject->getColumnOffset($invalidColumn); + } + + public function testSetColumnWithString() + { + $expectedResult = 'L'; + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setColumn($expectedResult); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + $result = $this->_testAutoFilterObject->getColumns(); + // Result should be an array of PHPExcel_Worksheet_AutoFilter_Column + // objects for each column we set indexed by the column ID + $this->assertInternalType('array', $result); + $this->assertEquals(1, count($result)); + $this->assertArrayHasKey($expectedResult,$result); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$expectedResult]); + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testSetInvalidColumnWithString() + { + $invalidColumn = 'A'; + + $result = $this->_testAutoFilterObject->setColumn($invalidColumn); + } + + public function testSetColumnWithColumnObject() + { + $expectedResult = 'M'; + $columnObject = new PHPExcel_Worksheet_AutoFilter_Column($expectedResult); + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setColumn($columnObject); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + $result = $this->_testAutoFilterObject->getColumns(); + // Result should be an array of PHPExcel_Worksheet_AutoFilter_Column + // objects for each column we set indexed by the column ID + $this->assertInternalType('array', $result); + $this->assertEquals(1, count($result)); + $this->assertArrayHasKey($expectedResult,$result); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$expectedResult]); + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testSetInvalidColumnWithObject() + { + $invalidColumn = 'E'; + $columnObject = new PHPExcel_Worksheet_AutoFilter_Column($invalidColumn); + + $result = $this->_testAutoFilterObject->setColumn($invalidColumn); + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testSetColumnWithInvalidDataType() + { + $invalidColumn = 123.456; + $columnObject = new PHPExcel_Worksheet_AutoFilter_Column($invalidColumn); + + $result = $this->_testAutoFilterObject->setColumn($invalidColumn); + } + + public function testGetColumns() + { + $columnIndexes = array('L','M'); + + foreach($columnIndexes as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + + $result = $this->_testAutoFilterObject->getColumns(); + // Result should be an array of PHPExcel_Worksheet_AutoFilter_Column + // objects for each column we set indexed by the column ID + $this->assertInternalType('array', $result); + $this->assertEquals(count($columnIndexes), count($result)); + foreach($columnIndexes as $columnIndex) { + $this->assertArrayHasKey($columnIndex,$result); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$columnIndex]); + } + } + + public function testGetColumn() + { + $columnIndexes = array('L','M'); + + foreach($columnIndexes as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + + // If we request a specific column by its column ID, we should + // get a PHPExcel_Worksheet_AutoFilter_Column object returned + foreach($columnIndexes as $columnIndex) { + $result = $this->_testAutoFilterObject->getColumn($columnIndex); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + } + } + + public function testGetColumnIfNotSet() + { + // If we request a specific column by its column ID, we should + // get a PHPExcel_Worksheet_AutoFilter_Column object returned + $result = $this->_testAutoFilterObject->getColumn('K'); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testGetColumnWithoutRangeSet() + { + // Clear the range + $result = $this->_testAutoFilterObject->setRange(); + + $result = $this->_testAutoFilterObject->getColumn('A'); + } + + public function testClearRangeWithExistingColumns() + { + $expectedResult = ''; + + $columnIndexes = array('L','M','N'); + foreach($columnIndexes as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setRange(); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + // Range should be cleared + $result = $this->_testAutoFilterObject->getRange(); + $this->assertEquals($expectedResult, $result); + + // Column array should be cleared + $result = $this->_testAutoFilterObject->getColumns(); + $this->assertInternalType('array', $result); + $this->assertEquals(0, count($result)); + } + + public function testSetRangeWithExistingColumns() + { + $expectedResult = 'G1:J512'; + + // These columns should be retained + $columnIndexes1 = array('I','J'); + foreach($columnIndexes1 as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + // These columns should be discarded + $columnIndexes2 = array('K','L','M'); + foreach($columnIndexes2 as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setRange($expectedResult); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + // Range should be correctly set + $result = $this->_testAutoFilterObject->getRange(); + $this->assertEquals($expectedResult, $result); + + // Only columns that existed in the original range and that + // still fall within the new range should be retained + $result = $this->_testAutoFilterObject->getColumns(); + $this->assertInternalType('array', $result); + $this->assertEquals(count($columnIndexes1), count($result)); + } + + public function testClone() + { + $columnIndexes = array('L','M'); + + foreach($columnIndexes as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + + $result = clone $this->_testAutoFilterObject; + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + } + +}