From 83feae3f351c52b725cd784ce1323a5caeffe20d Mon Sep 17 00:00:00 2001 From: aswinkumar863 Date: Sun, 29 May 2022 19:38:43 +0530 Subject: [PATCH] AutoFilter inside Tables Worksheet autofilter and autofilter inside tables share the same XML structure. By taking advantage of that, I just added a simple reference to the worksheet autofilter inside the table. In this commit: - Added autofilter inside tables. - Implemented XLSX writer and reader. - Refactored autofilter writer and reader. - Added additional unit test. - Fixed the broken test (testLoadOffice365AutoFilter). --- phpstan-baseline.neon | 19 +-- samples/Table/01_Table.php | 24 +++- src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php | 18 ++- .../Reader/Xlsx/TableReader.php | 4 +- src/PhpSpreadsheet/Worksheet/Table.php | 31 ++++- src/PhpSpreadsheet/Writer/Xlsx/AutoFilter.php | 117 ++++++++++++++++++ src/PhpSpreadsheet/Writer/Xlsx/Table.php | 3 + src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 101 ++------------- .../AutoFilter/Xlsx/BasicLoadTest.php | 29 +++-- .../Worksheet/Table/TableTest.php | 22 ++++ 10 files changed, 241 insertions(+), 127 deletions(-) create mode 100644 src/PhpSpreadsheet/Writer/Xlsx/AutoFilter.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 778090a8..200dd26b 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2260,11 +2260,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Reader/Xlsx.php - - - message: "#^Comparison operation \"\\>\" between SimpleXMLElement\\|null and 0 results in an error\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:boolean\\(\\) has parameter \\$value with no type specified\\.$#" count: 1 @@ -2452,17 +2447,7 @@ parameters: - message: "#^Parameter \\#1 \\$operator of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:setRule\\(\\) expects string, null given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 + count: 4 path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - @@ -4827,7 +4812,7 @@ parameters: - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" - count: 15 + count: 12 path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - diff --git a/samples/Table/01_Table.php b/samples/Table/01_Table.php index 476f187c..eebd60d1 100644 --- a/samples/Table/01_Table.php +++ b/samples/Table/01_Table.php @@ -1,6 +1,7 @@ getActiveSheet()->fromArray($dataArray, null, 'A2'); // Create Table $helper->log('Create Table'); -$table = new Table('A1:D17', 'Sales_Data'); +$table = new Table('A1:D33', 'Sales_Data'); // Create Columns $table->getColumn('D')->setShowFilterButton(false); +$table->getAutoFilter()->getColumn('A') + ->setFilterType(AutoFilter\Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER) + ->createRule() + ->setRule(AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, 2011) + ->setRuleType(AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); // Create Table Style $helper->log('Create Table Style'); diff --git a/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php b/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php index 374da9f6..77c36f7b 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php +++ b/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php @@ -4,18 +4,28 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx; use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column; use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule; +use PhpOffice\PhpSpreadsheet\Worksheet\Table; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use SimpleXMLElement; class AutoFilter { - private $worksheet; + /** + * @var Table|Worksheet + */ + private $parent; + /** + * @var SimpleXMLElement + */ private $worksheetXml; - public function __construct(Worksheet $workSheet, SimpleXMLElement $worksheetXml) + /** + * @param Table|Worksheet $parent + */ + public function __construct($parent, SimpleXMLElement $worksheetXml) { - $this->worksheet = $workSheet; + $this->parent = $parent; $this->worksheetXml = $worksheetXml; } @@ -30,7 +40,7 @@ class AutoFilter private function readAutoFilter($autoFilterRange, $xmlSheet): void { - $autoFilter = $this->worksheet->getAutoFilter(); + $autoFilter = $this->parent->getAutoFilter(); $autoFilter->setRange($autoFilterRange); foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { diff --git a/src/PhpSpreadsheet/Reader/Xlsx/TableReader.php b/src/PhpSpreadsheet/Reader/Xlsx/TableReader.php index e2c06da0..13df1c25 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx/TableReader.php +++ b/src/PhpSpreadsheet/Reader/Xlsx/TableReader.php @@ -51,6 +51,7 @@ class TableReader $this->readTableColumns($table, $tableXml->tableColumns); $this->readTableStyle($table, $tableXml->tableStyleInfo); + (new AutoFilter($table, $tableXml))->load(); $this->worksheet->addTable($table); } @@ -70,8 +71,9 @@ class TableReader */ private function readTableColumns(Table $table, SimpleXMLElement $tableColumnsXml): void { + $offset = 0; foreach ($tableColumnsXml->tableColumn as $tableColumn) { - $column = $table->getColumnByOffset((int) $tableColumn['id'] - 1); + $column = $table->getColumnByOffset($offset++); if ($table->getShowTotalsRow()) { if ($tableColumn['totalsRowLabel']) { diff --git a/src/PhpSpreadsheet/Worksheet/Table.php b/src/PhpSpreadsheet/Worksheet/Table.php index ffdbf9a7..e2da5c4f 100644 --- a/src/PhpSpreadsheet/Worksheet/Table.php +++ b/src/PhpSpreadsheet/Worksheet/Table.php @@ -59,6 +59,13 @@ class Table */ private $style; + /** + * Table AutoFilter. + * + * @var AutoFilter + */ + private $autoFilter; + /** * Create a new Table. * @@ -70,9 +77,10 @@ class Table */ public function __construct($range = '', string $name = '') { + $this->style = new TableStyle(); + $this->autoFilter = new AutoFilter($range); $this->setRange($range); $this->setName($name); - $this->style = new TableStyle(); } /** @@ -193,6 +201,8 @@ class Table } $this->range = $range; + $this->autoFilter->setRange($range); + // Discard any column ruless that are no longer valid within this range [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range); foreach ($this->columns as $key => $value) { @@ -248,6 +258,7 @@ class Table } $this->workSheet = $worksheet; + $this->autoFilter->setParent($worksheet); return $this; } @@ -415,6 +426,24 @@ class Table return $this; } + /** + * Get AutoFilter. + */ + public function getAutoFilter(): AutoFilter + { + return $this->autoFilter; + } + + /** + * Set AutoFilter. + */ + public function setAutoFilter(AutoFilter $autoFilter): self + { + $this->autoFilter = $autoFilter; + + return $this; + } + /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ diff --git a/src/PhpSpreadsheet/Writer/Xlsx/AutoFilter.php b/src/PhpSpreadsheet/Writer/Xlsx/AutoFilter.php new file mode 100644 index 00000000..8b0f8884 --- /dev/null +++ b/src/PhpSpreadsheet/Writer/Xlsx/AutoFilter.php @@ -0,0 +1,117 @@ +getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + // autoFilter + $objWriter->startElement('autoFilter'); + + // Strip any worksheet reference from the filter coordinates + $range = Coordinate::splitRange($autoFilterRange); + $range = $range[0]; + // Strip any worksheet ref + [$ws, $range[0]] = Worksheet::extractSheetTitle($range[0], true); + $range = implode(':', $range); + + $objWriter->writeAttribute('ref', str_replace('$', '', $range)); + + $columns = $worksheet->getAutoFilter()->getColumns(); + if (count($columns) > 0) { + foreach ($columns as $columnID => $column) { + $colId = $worksheet->getAutoFilter()->getColumnOffset($columnID); + self::writeAutoFilterColumn($objWriter, $column, $colId); + } + } + $objWriter->endElement(); + } + } + + /** + * Write AutoFilter's filterColumn. + */ + public static function writeAutoFilterColumn(XMLWriter $objWriter, Column $column, int $colId): void + { + $rules = $column->getRules(); + if (count($rules) > 0) { + $objWriter->startElement('filterColumn'); + $objWriter->writeAttribute('colId', "$colId"); + + $objWriter->startElement($column->getFilterType()); + if ($column->getJoin() == Column::AUTOFILTER_COLUMN_JOIN_AND) { + $objWriter->writeAttribute('and', '1'); + } + + foreach ($rules as $rule) { + if ( + ($column->getFilterType() === Column::AUTOFILTER_FILTERTYPE_FILTER) && + ($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_EQUAL) && + ($rule->getValue() === '') + ) { + // Filter rule for Blanks + $objWriter->writeAttribute('blank', '1'); + } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { + // Dynamic Filter Rule + $objWriter->writeAttribute('type', $rule->getGrouping()); + $val = $column->getAttribute('val'); + if ($val !== null) { + $objWriter->writeAttribute('val', "$val"); + } + $maxVal = $column->getAttribute('maxVal'); + if ($maxVal !== null) { + $objWriter->writeAttribute('maxVal', "$maxVal"); + } + } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { + // Top 10 Filter Rule + $ruleValue = $rule->getValue(); + if (!is_array($ruleValue)) { + $objWriter->writeAttribute('val', "$ruleValue"); + } + $objWriter->writeAttribute('percent', (($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); + $objWriter->writeAttribute('top', (($rule->getGrouping() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1' : '0')); + } else { + // Filter, DateGroupItem or CustomFilter + $objWriter->startElement($rule->getRuleType()); + + if ($rule->getOperator() !== Rule::AUTOFILTER_COLUMN_RULE_EQUAL) { + $objWriter->writeAttribute('operator', $rule->getOperator()); + } + if ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DATEGROUP) { + // Date Group filters + $ruleValue = $rule->getValue(); + if (is_array($ruleValue)) { + foreach ($ruleValue as $key => $value) { + $objWriter->writeAttribute($key, "$value"); + } + } + $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); + } else { + $ruleValue = $rule->getValue(); + if (!is_array($ruleValue)) { + $objWriter->writeAttribute('val', "$ruleValue"); + } + } + + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + } +} diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Table.php b/src/PhpSpreadsheet/Writer/Xlsx/Table.php index 67dbd19b..a974c6cb 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Table.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Table.php @@ -57,6 +57,9 @@ class Table extends WriterPart $objWriter->writeAttribute('colId', (string) $offset); $objWriter->writeAttribute('hiddenButton', '1'); $objWriter->endElement(); + } else { + $column = $table->getAutoFilter()->getColumnByOffset($offset); + AutoFilter::writeAutoFilterColumn($objWriter, $column, $offset); } } $objWriter->endElement(); diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index cdc7c941..be65d163 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -3,7 +3,6 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; -use PhpOffice\PhpSpreadsheet\Calculation\Information\Value; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\RichText\RichText; @@ -13,8 +12,6 @@ use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormattingRuleExtension; -use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column; -use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule; use PhpOffice\PhpSpreadsheet\Worksheet\SheetView; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet as PhpspreadsheetWorksheet; @@ -154,6 +151,14 @@ class Worksheet extends WriterPart $worksheet->getAutoFilter()->showHideRows(); } } + $tables = $worksheet->getTableCollection(); + if (count($tables)) { + foreach ($tables as $table) { + if (!$table->getAutoFilter()->getEvaluated()) { + $table->getAutoFilter()->showHideRows(); + } + } + } // tabColor if ($worksheet->isTabColorSet()) { @@ -905,95 +910,7 @@ class Worksheet extends WriterPart */ private function writeAutoFilter(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void { - $autoFilterRange = $worksheet->getAutoFilter()->getRange(); - if (!empty($autoFilterRange)) { - // autoFilter - $objWriter->startElement('autoFilter'); - - // Strip any worksheet reference from the filter coordinates - $range = Coordinate::splitRange($autoFilterRange); - $range = $range[0]; - // Strip any worksheet ref - [$ws, $range[0]] = PhpspreadsheetWorksheet::extractSheetTitle($range[0], true); - $range = implode(':', $range); - - $objWriter->writeAttribute('ref', str_replace('$', '', $range)); - - $columns = $worksheet->getAutoFilter()->getColumns(); - if (count($columns) > 0) { - foreach ($columns as $columnID => $column) { - $rules = $column->getRules(); - if (count($rules) > 0) { - $objWriter->startElement('filterColumn'); - $objWriter->writeAttribute('colId', $worksheet->getAutoFilter()->getColumnOffset($columnID)); - - $objWriter->startElement($column->getFilterType()); - if ($column->getJoin() == Column::AUTOFILTER_COLUMN_JOIN_AND) { - $objWriter->writeAttribute('and', 1); - } - - foreach ($rules as $rule) { - if ( - ($column->getFilterType() === Column::AUTOFILTER_FILTERTYPE_FILTER) && - ($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_EQUAL) && - ($rule->getValue() === '') - ) { - // Filter rule for Blanks - $objWriter->writeAttribute('blank', 1); - } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { - // Dynamic Filter Rule - $objWriter->writeAttribute('type', $rule->getGrouping()); - $val = $column->getAttribute('val'); - if ($val !== null) { - $objWriter->writeAttribute('val', "$val"); - } - $maxVal = $column->getAttribute('maxVal'); - if ($maxVal !== null) { - $objWriter->writeAttribute('maxVal', "$maxVal"); - } - } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { - // Top 10 Filter Rule - $ruleValue = $rule->getValue(); - if (!is_array($ruleValue)) { - $objWriter->writeAttribute('val', "$ruleValue"); - } - $objWriter->writeAttribute('percent', (($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); - $objWriter->writeAttribute('top', (($rule->getGrouping() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1' : '0')); - } else { - // Filter, DateGroupItem or CustomFilter - $objWriter->startElement($rule->getRuleType()); - - if ($rule->getOperator() !== Rule::AUTOFILTER_COLUMN_RULE_EQUAL) { - $objWriter->writeAttribute('operator', $rule->getOperator()); - } - if ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DATEGROUP) { - // Date Group filters - $ruleValue = $rule->getValue(); - if (is_array($ruleValue)) { - foreach ($ruleValue as $key => $value) { - $objWriter->writeAttribute($key, "$value"); - } - } - $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); - } else { - $ruleValue = $rule->getValue(); - if (!is_array($ruleValue)) { - $objWriter->writeAttribute('val', "$ruleValue"); - } - } - - $objWriter->endElement(); - } - } - - $objWriter->endElement(); - - $objWriter->endElement(); - } - } - } - $objWriter->endElement(); - } + AutoFilter::writeAutoFilter($objWriter, $worksheet); } /** diff --git a/tests/PhpSpreadsheetTests/Features/AutoFilter/Xlsx/BasicLoadTest.php b/tests/PhpSpreadsheetTests/Features/AutoFilter/Xlsx/BasicLoadTest.php index c36e6741..63c3c6fd 100644 --- a/tests/PhpSpreadsheetTests/Features/AutoFilter/Xlsx/BasicLoadTest.php +++ b/tests/PhpSpreadsheetTests/Features/AutoFilter/Xlsx/BasicLoadTest.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Features\AutoFilter\Xlsx; use PhpOffice\PhpSpreadsheet\Reader\Xlsx; use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule; +use PhpOffice\PhpSpreadsheet\Worksheet\Table; use PHPUnit\Framework\TestCase; class BasicLoadTest extends TestCase @@ -47,28 +48,34 @@ class BasicLoadTest extends TestCase $spreadsheet = $reader->load($filename); $worksheet = $spreadsheet->getActiveSheet(); - self::assertSame('A1:D57', $worksheet->getAutoFilter()->getRange()); - self::assertSame(2, $worksheet->getAutoFilter()->getColumn('C')->ruleCount()); + $tables = $worksheet->getTableCollection(); + self::assertCount(1, $tables); + + $table = $tables->offsetGet(0); + self::assertInstanceOf(Table::class, $table); + + self::assertSame('A1:D57', $table->getAutoFilter()->getRange()); + self::assertSame(2, $table->getAutoFilter()->getColumn('C')->ruleCount()); self::assertSame( Rule::AUTOFILTER_COLUMN_RULE_EQUAL, - $worksheet->getAutoFilter()->getColumn('C')->getRules()[0]->getOperator() + $table->getAutoFilter()->getColumn('C')->getRules()[0]->getOperator() ); - self::assertSame('UK', $worksheet->getAutoFilter()->getColumn('C')->getRules()[0]->getValue()); + self::assertSame('UK', $table->getAutoFilter()->getColumn('C')->getRules()[0]->getValue()); self::assertSame( Rule::AUTOFILTER_COLUMN_RULE_EQUAL, - $worksheet->getAutoFilter()->getColumn('C')->getRules()[1]->getOperator() + $table->getAutoFilter()->getColumn('C')->getRules()[1]->getOperator() ); - self::assertSame('United States', $worksheet->getAutoFilter()->getColumn('C')->getRules()[1]->getValue()); - self::assertSame(2, $worksheet->getAutoFilter()->getColumn('D')->ruleCount()); + self::assertSame('United States', $table->getAutoFilter()->getColumn('C')->getRules()[1]->getValue()); + self::assertSame(2, $table->getAutoFilter()->getColumn('D')->ruleCount()); self::assertSame( Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN, - $worksheet->getAutoFilter()->getColumn('D')->getRules()[0]->getOperator() + $table->getAutoFilter()->getColumn('D')->getRules()[0]->getOperator() ); - self::assertSame('650', $worksheet->getAutoFilter()->getColumn('D')->getRules()[0]->getValue()); + self::assertSame('650', $table->getAutoFilter()->getColumn('D')->getRules()[0]->getValue()); self::assertSame( Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, - $worksheet->getAutoFilter()->getColumn('D')->getRules()[1]->getOperator() + $table->getAutoFilter()->getColumn('D')->getRules()[1]->getOperator() ); - self::assertSame('800', $worksheet->getAutoFilter()->getColumn('D')->getRules()[1]->getValue()); + self::assertSame('800', $table->getAutoFilter()->getColumn('D')->getRules()[1]->getValue()); } } diff --git a/tests/PhpSpreadsheetTests/Worksheet/Table/TableTest.php b/tests/PhpSpreadsheetTests/Worksheet/Table/TableTest.php index c7cbee25..028816a7 100644 --- a/tests/PhpSpreadsheetTests/Worksheet/Table/TableTest.php +++ b/tests/PhpSpreadsheetTests/Worksheet/Table/TableTest.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Worksheet\Table; use PhpOffice\PhpSpreadsheet\Cell\CellAddress; use PhpOffice\PhpSpreadsheet\Cell\CellRange; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; +use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter; use PhpOffice\PhpSpreadsheet\Worksheet\Table; use PhpOffice\PhpSpreadsheet\Worksheet\Table\Column; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; @@ -555,4 +556,25 @@ class TableTest extends SetupTeardown self::assertArrayHasKey('L', $columns); self::assertArrayHasKey('M', $columns); } + + public function testAutoFilterRule(): void + { + $table = new Table(self::INITIAL_RANGE); + $columnFilter = $table->getAutoFilter()->getColumn('H'); + $columnFilter->setFilterType(AutoFilter\Column::AUTOFILTER_FILTERTYPE_FILTER); + $columnFilter->createRule() + ->setRule( + AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL, + 3 + ); + $autoFilterRuleObject = new AutoFilter\Column\Rule($columnFilter); + self::assertEquals(AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_FILTER, $autoFilterRuleObject->getRuleType()); + $ruleParent = $autoFilterRuleObject->getParent(); + if ($ruleParent === null) { + self::fail('Unexpected null parent'); + } else { + self::assertEquals('H', $ruleParent->getColumnIndex()); + self::assertSame($columnFilter, $ruleParent); + } + } }