Autofilter Part 2
Most of the remaining 32-bit-unsafe date handling that remains in PhpSpreadsheet is in AutoFilter. Cleaning this up demonstrated that there are a lot of problems with AutoFilter, and I will do it in two pieces. Part 1 was PR #2141 which I have just merged. In this PR: - Fix remaining 32-bit dates in filterTestInDateGroupSet. - Also in some of the existing AutoFilter samples. Note that the comments in two of those said the filter was being set for the first day of each month, but the code specifies the last day - I have corrected the comments. - Remove mocking in unit tests for AutoFilter in favor of 'real' tests. - Code coverage is now 100% in all of AutoFilter, AutoFilter/Column, and AutoFilter/Common/Rule. - No remaining AutoFilter(/Column(/Rule)) exceptions in Phpstan baseline. - Documentation for escaping of asterisk, question mark, and tilde in text filters included spurious backslashes which are now removed. - Text filter escaping of question mark did not work. There had been no unit tests for any text filtering. - Likewise there had been no testing for TopTen. - Above- and below- average filters were not working because they acquired their Calculation instance incorrectly. There had been no tests. - Several unchanging private static arrays in Rule were changed to private const arrays. - Clones are now tested. - RuleTest is moved to same directory as other tests.
This commit is contained in:
parent
5769885802
commit
a735afc088
|
|
@ -251,16 +251,16 @@ $columnFilter->createRule()
|
|||
);
|
||||
```
|
||||
|
||||
MS Excel uses \* as a wildcard to match any number of characters, and ?
|
||||
as a wildcard to match a single character. 'U\*' equates to "begins with
|
||||
a 'U'"; '\*U' equates to "ends with a 'U'"; and '\*U\*' equates to
|
||||
"contains a 'U'"
|
||||
MS Excel uses `*` as a wildcard to match any number of characters, and `?`
|
||||
as a wildcard to match a single character. `U*` equates to "begins with
|
||||
a 'U'"; `*U` equates to "ends with a 'U'"; and `*U*` equates to
|
||||
"contains a 'U'".
|
||||
|
||||
If you want to match explicitly against a \* or a ? character, you can
|
||||
escape it with a tilde (\~), so ?\~\*\* would explicitly match for a \*
|
||||
character as the second character in the cell value, followed by any
|
||||
If you want to match explicitly against `*` or `?`, you can
|
||||
escape it with a tilde `~`, so `?~**` would explicitly match for `*`
|
||||
as the second character in the cell value, followed by any
|
||||
number of other characters. The only other character that needs escaping
|
||||
is the \~ itself.
|
||||
is the `~` itself.
|
||||
|
||||
To create a "between" condition, we need to define two rules:
|
||||
|
||||
|
|
|
|||
|
|
@ -5290,156 +5290,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Style/Style.php
|
||||
|
||||
-
|
||||
message: "#^Result of && is always true\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$excelTimestamp of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Date\\:\\:excelToTimestamp\\(\\) expects float\\|int, float\\|int\\|string given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$number of function floor expects float, float\\|int\\<1, max\\>\\|string given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:\\$toReplace has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has parameter \\$columnID with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has parameter \\$endRow with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has parameter \\$ruleType with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has parameter \\$ruleValue with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has parameter \\$startRow with no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method rangeToArray\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getRowDimension\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Cannot assign offset 'year' to array\\<string\\>\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Cannot assign offset 'month' to array\\<string\\>\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Cannot assign offset 'day' to array\\<string\\>\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Cannot assign offset 'hour' to array\\<string\\>\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Cannot assign offset 'minute' to array\\<string\\>\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Cannot assign offset 'second' to array\\<string\\>\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$str of function preg_quote expects string, array\\<string\\>\\|string given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"\\*\" between 0\\|array\\<string\\>\\|string and float\\|int results in an error\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Left side of && is always true\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$function of function call_user_func_array expects callable\\(\\)\\: mixed, array\\('PhpOffice\\\\\\\\PhpSpreadsheet\\\\\\\\Worksheet\\\\\\\\AutoFilter', mixed\\) given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$ruleTypes has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$dateTimeGroups has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$dynamicTypes has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$operators has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$topTenValue has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$topTenType has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$parent \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
|
||||
count: 1
|
||||
|
|
@ -7030,16 +6880,6 @@ parameters:
|
|||
count: 2
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, array\\<string\\>\\|string given\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Argument of an invalid type array\\<string\\>\\|string supplied for foreach, only iterables are supported\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int\\|string given\\.$#"
|
||||
count: 1
|
||||
|
|
@ -7270,11 +7110,6 @@ parameters:
|
|||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Style/ConditionalTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$pValue of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:setValue\\(\\) expects array\\<string\\>\\|string, int given\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Worksheet/AutoFilter/Column/RuleTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$pValue of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\:\\:setAttribute\\(\\) expects string, int given\\.$#"
|
||||
count: 1
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ $spreadsheet->getActiveSheet()->setCellValue('A1', 'Financial Year')
|
|||
->setCellValue('D1', 'Date')
|
||||
->setCellValue('E1', 'Sales Value')
|
||||
->setCellValue('F1', 'Expenditure');
|
||||
$startYear = $endYear = $currentYear = date('Y');
|
||||
$dateTime = new DateTime();
|
||||
$startYear = $endYear = $currentYear = (int) $dateTime->format('Y');
|
||||
--$startYear;
|
||||
++$endYear;
|
||||
|
||||
|
|
@ -52,7 +53,9 @@ $row = 2;
|
|||
foreach ($years as $year) {
|
||||
foreach ($periods as $period) {
|
||||
foreach ($countries as $country) {
|
||||
$endDays = date('t', mktime(0, 0, 0, $period, 1, (int) $year));
|
||||
$dateString = sprintf('%04d-%02d-01T00:00:00', $year, $period);
|
||||
$dateTime = new DateTime($dateString);
|
||||
$endDays = (int) $dateTime->format('t');
|
||||
for ($i = 1; $i <= $endDays; ++$i) {
|
||||
$eDate = Date::formattedPHPToExcel(
|
||||
$year,
|
||||
|
|
@ -124,10 +127,12 @@ $autoFilter->getColumn('C')
|
|||
'japan'
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
|
||||
// Filter the Date column on a filter value of the first day of every period of the current year
|
||||
// Filter the Date column on a filter value of the last day of every period of the current year
|
||||
// We us a dateGroup ruletype for this, although it is still a standard filter
|
||||
foreach ($periods as $period) {
|
||||
$endDate = date('t', mktime(0, 0, 0, $period, 1, (int) $currentYear));
|
||||
$dateString = sprintf('%04d-%02d-01T00:00:00', $currentYear, $period);
|
||||
$dateTime = new DateTime($dateString);
|
||||
$endDate = (int) $dateTime->format('t');
|
||||
|
||||
$autoFilter->getColumn('D')
|
||||
->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ $spreadsheet->getActiveSheet()->setCellValue('A1', 'Financial Year')
|
|||
->setCellValue('D1', 'Date')
|
||||
->setCellValue('E1', 'Sales Value')
|
||||
->setCellValue('F1', 'Expenditure');
|
||||
$startYear = $endYear = $currentYear = date('Y');
|
||||
$dateTime = new DateTime();
|
||||
$startYear = $endYear = $currentYear = (int) $dateTime->format('Y');
|
||||
--$startYear;
|
||||
++$endYear;
|
||||
|
||||
|
|
@ -52,7 +53,9 @@ $row = 2;
|
|||
foreach ($years as $year) {
|
||||
foreach ($periods as $period) {
|
||||
foreach ($countries as $country) {
|
||||
$endDays = date('t', mktime(0, 0, 0, $period, 1, (int) $year));
|
||||
$dateString = sprintf('%04d-%02d-01T00:00:00', $year, $period);
|
||||
$dateTime = new DateTime($dateString);
|
||||
$endDays = (int) $dateTime->format('t');
|
||||
for ($i = 1; $i <= $endDays; ++$i) {
|
||||
$eDate = Date::formattedPHPToExcel(
|
||||
$year,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ $spreadsheet->getActiveSheet()->setCellValue('A1', 'Financial Year')
|
|||
->setCellValue('D1', 'Date')
|
||||
->setCellValue('E1', 'Sales Value')
|
||||
->setCellValue('F1', 'Expenditure');
|
||||
$startYear = $endYear = $currentYear = date('Y');
|
||||
$dateTime = new DateTime();
|
||||
$startYear = $endYear = $currentYear = (int) $dateTime->format('Y');
|
||||
--$startYear;
|
||||
++$endYear;
|
||||
|
||||
|
|
@ -52,7 +53,9 @@ $row = 2;
|
|||
foreach ($years as $year) {
|
||||
foreach ($periods as $period) {
|
||||
foreach ($countries as $country) {
|
||||
$endDays = date('t', mktime(0, 0, 0, $period, 1, (int) $year));
|
||||
$dateString = sprintf('%04d-%02d-01T00:00:00', $year, $period);
|
||||
$dateTime = new DateTime($dateString);
|
||||
$endDays = (int) $dateTime->format('t');
|
||||
for ($i = 1; $i <= $endDays; ++$i) {
|
||||
$eDate = Date::formattedPHPToExcel(
|
||||
$year,
|
||||
|
|
@ -124,10 +127,12 @@ $autoFilter->getColumn('C')
|
|||
'japan'
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
|
||||
// Filter the Date column on a filter value of the first day of every period of the current year
|
||||
// Filter the Date column on a filter value of the last day of every period of the current year
|
||||
// We us a dateGroup ruletype for this, although it is still a standard filter
|
||||
foreach ($periods as $period) {
|
||||
$endDate = date('t', mktime(0, 0, 0, $period, 1, (int) $currentYear));
|
||||
$dateString = sprintf('%04d-%02d-01T00:00:00', $currentYear, $period);
|
||||
$dateTime = new DateTime($dateString);
|
||||
$endDate = (int) $dateTime->format('t');
|
||||
|
||||
$autoFilter->getColumn('D')
|
||||
->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER)
|
||||
|
|
|
|||
|
|
@ -91,19 +91,19 @@ class AutoFilter
|
|||
{
|
||||
// extract coordinate
|
||||
[$worksheet, $pRange] = Worksheet::extractSheetTitle($pRange, true);
|
||||
|
||||
if (strpos($pRange, ':') !== false) {
|
||||
$this->range = $pRange;
|
||||
} elseif (empty($pRange)) {
|
||||
$this->range = '';
|
||||
} else {
|
||||
throw new PhpSpreadsheetException('Autofilter must be set on a range of cells.');
|
||||
}
|
||||
|
||||
if (empty($pRange)) {
|
||||
// Discard all column rules
|
||||
$this->columns = [];
|
||||
} else {
|
||||
$this->range = '';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (strpos($pRange, ':') === false) {
|
||||
throw new PhpSpreadsheetException('Autofilter must be set on a range of cells.');
|
||||
}
|
||||
|
||||
$this->range = $pRange;
|
||||
// Discard any column rules that are no longer valid within this range
|
||||
[$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range);
|
||||
foreach ($this->columns as $key => $value) {
|
||||
|
|
@ -112,7 +112,6 @@ class AutoFilter
|
|||
unset($this->columns[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
|
@ -215,7 +214,7 @@ class AutoFilter
|
|||
|
||||
if (is_string($pColumn)) {
|
||||
$this->columns[$pColumn] = new AutoFilter\Column($pColumn, $this);
|
||||
} elseif (is_object($pColumn) && ($pColumn instanceof AutoFilter\Column)) {
|
||||
} else {
|
||||
$pColumn->setParent($this);
|
||||
$this->columns[$column] = $pColumn;
|
||||
}
|
||||
|
|
@ -306,20 +305,22 @@ class AutoFilter
|
|||
if (($cellValue == '') || ($cellValue === null)) {
|
||||
return $blanks;
|
||||
}
|
||||
$timeZone = new DateTimeZone('UTC');
|
||||
|
||||
if (is_numeric($cellValue)) {
|
||||
$dateValue = Date::excelToTimestamp($cellValue);
|
||||
$dateTime = Date::excelToDateTimeObject((float) $cellValue, $timeZone);
|
||||
$cellValue = (float) $cellValue;
|
||||
if ($cellValue < 1) {
|
||||
// Just the time part
|
||||
$dtVal = date('His', $dateValue);
|
||||
$dtVal = $dateTime->format('His');
|
||||
$dateSet = $dateSet['time'];
|
||||
} elseif ($cellValue == floor($cellValue)) {
|
||||
// Just the date part
|
||||
$dtVal = date('Ymd', $dateValue);
|
||||
$dtVal = $dateTime->format('Ymd');
|
||||
$dateSet = $dateSet['date'];
|
||||
} else {
|
||||
// date and time parts
|
||||
$dtVal = date('YmdHis', $dateValue);
|
||||
$dtVal = $dateTime->format('YmdHis');
|
||||
$dateSet = $dateSet['dateTime'];
|
||||
}
|
||||
foreach ($dateSet as $dateValue) {
|
||||
|
|
@ -453,12 +454,10 @@ class AutoFilter
|
|||
|
||||
/**
|
||||
* Search/Replace arrays to convert Excel wildcard syntax to a regexp syntax for preg_matching.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $fromReplace = ['\*', '\?', '~~', '~.*', '~.?'];
|
||||
private const FROM_REPLACE = ['~~', '~\\*', '\\*', '~\\?', '\\?', "\x1c"];
|
||||
|
||||
private static $toReplace = ['.*', '.', '~', '\*', '\?'];
|
||||
private const TO_REPLACE = ["\x1c", '[*]', '.*', '[?]', '.', '~'];
|
||||
|
||||
private static function makeDateObject(int $year, int $month, int $day, int $hour = 0, int $minute = 0, int $second = 0): DateTime
|
||||
{
|
||||
|
|
@ -710,12 +709,25 @@ class AutoFilter
|
|||
return ['method' => 'filterTestInCustomDataSet', 'arguments' => ['filterRules' => $ruleValues, 'join' => AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_AND]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the AutoFilter rules to the AutoFilter Range.
|
||||
*
|
||||
* @param string $columnID
|
||||
* @param int $startRow
|
||||
* @param int $endRow
|
||||
* @param ?string $ruleType
|
||||
* @param mixed $ruleValue
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function calculateTopTenValue($columnID, $startRow, $endRow, $ruleType, $ruleValue)
|
||||
{
|
||||
$range = $columnID . $startRow . ':' . $columnID . $endRow;
|
||||
$retVal = null;
|
||||
if ($this->workSheet !== null) {
|
||||
$dataValues = Functions::flattenArray($this->workSheet->rangeToArray($range, null, true, false));
|
||||
|
||||
$dataValues = array_filter($dataValues);
|
||||
|
||||
if ($ruleType == Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) {
|
||||
rsort($dataValues);
|
||||
} else {
|
||||
|
|
@ -724,7 +736,10 @@ class AutoFilter
|
|||
|
||||
$slice = array_slice($dataValues, 0, $ruleValue);
|
||||
|
||||
return array_pop($slice);
|
||||
$retVal = array_pop($slice);
|
||||
}
|
||||
|
||||
return $retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -734,6 +749,9 @@ class AutoFilter
|
|||
*/
|
||||
public function showHideRows()
|
||||
{
|
||||
if ($this->workSheet === null) {
|
||||
return $this;
|
||||
}
|
||||
[$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range);
|
||||
|
||||
// The heading row should always be visible
|
||||
|
|
@ -771,6 +789,9 @@ class AutoFilter
|
|||
'dateTime' => [],
|
||||
];
|
||||
foreach ($ruleDataSet as $ruleValue) {
|
||||
if (!is_array($ruleValue)) {
|
||||
continue;
|
||||
}
|
||||
$date = $time = '';
|
||||
if (
|
||||
(isset($ruleValue[Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) &&
|
||||
|
|
@ -830,10 +851,10 @@ class AutoFilter
|
|||
// Build a list of the filter value selections
|
||||
foreach ($rules as $rule) {
|
||||
$ruleValue = $rule->getValue();
|
||||
if (!is_numeric($ruleValue)) {
|
||||
if (!is_array($ruleValue) && !is_numeric($ruleValue)) {
|
||||
// Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards
|
||||
$ruleValue = preg_quote($ruleValue);
|
||||
$ruleValue = str_replace(self::$fromReplace, self::$toReplace, $ruleValue);
|
||||
$ruleValue = preg_quote("$ruleValue");
|
||||
$ruleValue = str_replace(self::FROM_REPLACE, self::TO_REPLACE, $ruleValue);
|
||||
if (trim($ruleValue) == '') {
|
||||
$customRuleForBlanks = true;
|
||||
$ruleValue = trim($ruleValue);
|
||||
|
|
@ -860,7 +881,8 @@ class AutoFilter
|
|||
// Number (Average) based
|
||||
// Calculate the average
|
||||
$averageFormula = '=AVERAGE(' . $columnID . ($rangeStart[1] + 1) . ':' . $columnID . $rangeEnd[1] . ')';
|
||||
$average = Calculation::getInstance()->calculateFormula($averageFormula, null, $this->workSheet->getCell('A1'));
|
||||
$spreadsheet = ($this->workSheet === null) ? null : $this->workSheet->getParent();
|
||||
$average = Calculation::getInstance($spreadsheet)->calculateFormula($averageFormula, null, $this->workSheet->getCell('A1'));
|
||||
// Set above/below rule based on greaterThan or LessTan
|
||||
$operator = ($dynamicRuleType === Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE)
|
||||
? Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN
|
||||
|
|
@ -915,8 +937,8 @@ class AutoFilter
|
|||
$ruleValue = $rule->getValue();
|
||||
$ruleOperator = $rule->getOperator();
|
||||
}
|
||||
if ($ruleOperator === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) {
|
||||
$ruleValue = floor($ruleValue * ($dataRowCount / 100));
|
||||
if (is_numeric($ruleValue) && $ruleOperator === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) {
|
||||
$ruleValue = floor((float) $ruleValue * ($dataRowCount / 100));
|
||||
}
|
||||
if (!is_array($ruleValue) && $ruleValue < 1) {
|
||||
$ruleValue = 1;
|
||||
|
|
@ -947,18 +969,16 @@ class AutoFilter
|
|||
foreach ($columnFilterTests as $columnID => $columnFilterTest) {
|
||||
$cellValue = $this->workSheet->getCell($columnID . $row)->getCalculatedValue();
|
||||
// Execute the filter test
|
||||
$result = $result &&
|
||||
call_user_func_array(
|
||||
[self::class, $columnFilterTest['method']],
|
||||
[$cellValue, $columnFilterTest['arguments']]
|
||||
);
|
||||
$result = // $result && // phpstan says $result is always true here
|
||||
// @phpstan-ignore-next-line
|
||||
call_user_func_array([self::class, $columnFilterTest['method']], [$cellValue, $columnFilterTest['arguments']]);
|
||||
// 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
|
||||
$this->workSheet->getRowDimension($row)->setVisible($result);
|
||||
$this->workSheet->getRowDimension((int) $row)->setVisible($result);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ class Column
|
|||
/**
|
||||
* Get AutoFilter Column Attributes.
|
||||
*
|
||||
* @return string[]
|
||||
* @return int[]|string[]
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
|
|
@ -256,7 +256,7 @@ class Column
|
|||
*
|
||||
* @param string $pName Attribute Name
|
||||
*
|
||||
* @return null|string
|
||||
* @return null|int|string
|
||||
*/
|
||||
public function getAttribute($pName)
|
||||
{
|
||||
|
|
@ -370,8 +370,6 @@ class Column
|
|||
$cloned->setParent($this); // attach the new cloned Rule to this new cloned Autofilter Cloned object
|
||||
$this->ruleset[$k] = $cloned;
|
||||
}
|
||||
} elseif (is_object($value)) {
|
||||
$this->$key = clone $value;
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class Rule
|
|||
const AUTOFILTER_RULETYPE_DYNAMICFILTER = 'dynamicFilter';
|
||||
const AUTOFILTER_RULETYPE_TOPTENFILTER = 'top10Filter';
|
||||
|
||||
private static $ruleTypes = [
|
||||
private const RULE_TYPES = [
|
||||
// Currently we're not handling
|
||||
// colorFilter
|
||||
// extLst
|
||||
|
|
@ -32,7 +32,7 @@ class Rule
|
|||
const AUTOFILTER_RULETYPE_DATEGROUP_MINUTE = 'minute';
|
||||
const AUTOFILTER_RULETYPE_DATEGROUP_SECOND = 'second';
|
||||
|
||||
private static $dateTimeGroups = [
|
||||
private const DATE_TIME_GROUPS = [
|
||||
self::AUTOFILTER_RULETYPE_DATEGROUP_YEAR,
|
||||
self::AUTOFILTER_RULETYPE_DATEGROUP_MONTH,
|
||||
self::AUTOFILTER_RULETYPE_DATEGROUP_DAY,
|
||||
|
|
@ -88,7 +88,7 @@ class Rule
|
|||
const AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE = 'aboveAverage';
|
||||
const AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE = 'belowAverage';
|
||||
|
||||
private static $dynamicTypes = [
|
||||
private const DYNAMIC_TYPES = [
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_TODAY,
|
||||
self::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW,
|
||||
|
|
@ -141,7 +141,7 @@ class Rule
|
|||
const AUTOFILTER_COLUMN_RULE_LESSTHAN = 'lessThan';
|
||||
const AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL = 'lessThanOrEqual';
|
||||
|
||||
private static $operators = [
|
||||
private const OPERATORS = [
|
||||
self::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
self::AUTOFILTER_COLUMN_RULE_NOTEQUAL,
|
||||
self::AUTOFILTER_COLUMN_RULE_GREATERTHAN,
|
||||
|
|
@ -153,7 +153,7 @@ class Rule
|
|||
const AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE = 'byValue';
|
||||
const AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT = 'byPercent';
|
||||
|
||||
private static $topTenValue = [
|
||||
private const TOP_TEN_VALUE = [
|
||||
self::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE,
|
||||
self::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT,
|
||||
];
|
||||
|
|
@ -161,7 +161,7 @@ class Rule
|
|||
const AUTOFILTER_COLUMN_RULE_TOPTEN_TOP = 'top';
|
||||
const AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM = 'bottom';
|
||||
|
||||
private static $topTenType = [
|
||||
private const TOP_TEN_TYPE = [
|
||||
self::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP,
|
||||
self::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM,
|
||||
];
|
||||
|
|
@ -203,7 +203,7 @@ class Rule
|
|||
/**
|
||||
* Autofilter Column.
|
||||
*
|
||||
* @var Column
|
||||
* @var ?Column
|
||||
*/
|
||||
private $parent;
|
||||
|
||||
|
|
@ -217,7 +217,7 @@ class Rule
|
|||
/**
|
||||
* Autofilter Rule Value.
|
||||
*
|
||||
* @var string|string[]
|
||||
* @var int|int[]|string|string[]
|
||||
*/
|
||||
private $value = '';
|
||||
|
||||
|
|
@ -237,8 +237,6 @@ class Rule
|
|||
|
||||
/**
|
||||
* Create a new Rule.
|
||||
*
|
||||
* @param Column $pParent
|
||||
*/
|
||||
public function __construct(?Column $pParent = null)
|
||||
{
|
||||
|
|
@ -264,7 +262,7 @@ class Rule
|
|||
*/
|
||||
public function setRuleType($pRuleType)
|
||||
{
|
||||
if (!in_array($pRuleType, self::$ruleTypes)) {
|
||||
if (!in_array($pRuleType, self::RULE_TYPES)) {
|
||||
throw new PhpSpreadsheetException('Invalid rule type for column AutoFilter Rule.');
|
||||
}
|
||||
|
||||
|
|
@ -276,7 +274,7 @@ class Rule
|
|||
/**
|
||||
* Get AutoFilter Rule Value.
|
||||
*
|
||||
* @return string|string[]
|
||||
* @return int|int[]|string|string[]
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
|
|
@ -286,7 +284,7 @@ class Rule
|
|||
/**
|
||||
* Set AutoFilter Rule Value.
|
||||
*
|
||||
* @param string|string[] $pValue
|
||||
* @param int|int[]|string|string[] $pValue
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
|
|
@ -296,19 +294,19 @@ class Rule
|
|||
$grouping = -1;
|
||||
foreach ($pValue as $key => $value) {
|
||||
// Validate array entries
|
||||
if (!in_array($key, self::$dateTimeGroups)) {
|
||||
if (!in_array($key, self::DATE_TIME_GROUPS)) {
|
||||
// Remove any invalid entries from the value array
|
||||
unset($pValue[$key]);
|
||||
} else {
|
||||
// Work out what the dateTime grouping will be
|
||||
$grouping = max($grouping, array_search($key, self::$dateTimeGroups));
|
||||
$grouping = max($grouping, array_search($key, self::DATE_TIME_GROUPS));
|
||||
}
|
||||
}
|
||||
if (count($pValue) == 0) {
|
||||
throw new PhpSpreadsheetException('Invalid rule value for column AutoFilter Rule.');
|
||||
}
|
||||
// Set the dateTime grouping that we've anticipated
|
||||
$this->setGrouping(self::$dateTimeGroups[$grouping]);
|
||||
$this->setGrouping(self::DATE_TIME_GROUPS[$grouping]);
|
||||
}
|
||||
$this->value = $pValue;
|
||||
|
||||
|
|
@ -338,8 +336,8 @@ class Rule
|
|||
$pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL;
|
||||
}
|
||||
if (
|
||||
(!in_array($pOperator, self::$operators)) &&
|
||||
(!in_array($pOperator, self::$topTenValue))
|
||||
(!in_array($pOperator, self::OPERATORS)) &&
|
||||
(!in_array($pOperator, self::TOP_TEN_VALUE))
|
||||
) {
|
||||
throw new PhpSpreadsheetException('Invalid operator for column AutoFilter Rule.');
|
||||
}
|
||||
|
|
@ -369,11 +367,11 @@ class Rule
|
|||
{
|
||||
if (
|
||||
($pGrouping !== null) &&
|
||||
(!in_array($pGrouping, self::$dateTimeGroups)) &&
|
||||
(!in_array($pGrouping, self::$dynamicTypes)) &&
|
||||
(!in_array($pGrouping, self::$topTenType))
|
||||
(!in_array($pGrouping, self::DATE_TIME_GROUPS)) &&
|
||||
(!in_array($pGrouping, self::DYNAMIC_TYPES)) &&
|
||||
(!in_array($pGrouping, self::TOP_TEN_TYPE))
|
||||
) {
|
||||
throw new PhpSpreadsheetException('Invalid rule type for column AutoFilter Rule.');
|
||||
throw new PhpSpreadsheetException('Invalid grouping for column AutoFilter Rule.');
|
||||
}
|
||||
$this->grouping = $pGrouping;
|
||||
|
||||
|
|
@ -384,7 +382,7 @@ class Rule
|
|||
* Set AutoFilter Rule.
|
||||
*
|
||||
* @param string $pOperator see self::AUTOFILTER_COLUMN_RULE_*
|
||||
* @param string|string[] $pValue
|
||||
* @param int|int[]|string|string[] $pValue
|
||||
* @param string $pGrouping
|
||||
*
|
||||
* @return $this
|
||||
|
|
@ -406,7 +404,7 @@ class Rule
|
|||
/**
|
||||
* Get this Rule's AutoFilter Column Parent.
|
||||
*
|
||||
* @return Column
|
||||
* @return ?Column
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
|
|
@ -416,8 +414,6 @@ class Rule
|
|||
/**
|
||||
* Set this Rule's AutoFilter Column Parent.
|
||||
*
|
||||
* @param Column $pParent
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParent(?Column $pParent = null)
|
||||
|
|
@ -435,11 +431,9 @@ class Rule
|
|||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $value) {
|
||||
if (is_object($value)) {
|
||||
if ($key == 'parent') {
|
||||
if ($key == 'parent') { // this is only object
|
||||
// Detach from autofilter column parent
|
||||
$this->$key = null;
|
||||
} else {
|
||||
$this->$key = clone $value;
|
||||
}
|
||||
} else {
|
||||
$this->$key = $value;
|
||||
|
|
|
|||
|
|
@ -917,15 +917,18 @@ class Worksheet extends WriterPart
|
|||
$objWriter->writeAttribute('type', $rule->getGrouping());
|
||||
$val = $column->getAttribute('val');
|
||||
if ($val !== null) {
|
||||
$objWriter->writeAttribute('val', $val);
|
||||
$objWriter->writeAttribute('val', "$val");
|
||||
}
|
||||
$maxVal = $column->getAttribute('maxVal');
|
||||
if ($maxVal !== null) {
|
||||
$objWriter->writeAttribute('maxVal', $maxVal);
|
||||
$objWriter->writeAttribute('maxVal', "$maxVal");
|
||||
}
|
||||
} elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) {
|
||||
// Top 10 Filter Rule
|
||||
$objWriter->writeAttribute('val', $rule->getValue());
|
||||
$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 {
|
||||
|
|
@ -937,14 +940,18 @@ class Worksheet extends WriterPart
|
|||
}
|
||||
if ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DATEGROUP) {
|
||||
// Date Group filters
|
||||
foreach ($rule->getValue() as $key => $value) {
|
||||
if ($value > '') {
|
||||
$objWriter->writeAttribute($key, $value);
|
||||
$ruleValue = $rule->getValue();
|
||||
if (is_array($ruleValue)) {
|
||||
foreach ($ruleValue as $key => $value) {
|
||||
$objWriter->writeAttribute($key, "$value");
|
||||
}
|
||||
}
|
||||
$objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping());
|
||||
} else {
|
||||
$objWriter->writeAttribute('val', $rule->getValue());
|
||||
$ruleValue = $rule->getValue();
|
||||
if (!is_array($ruleValue)) {
|
||||
$objWriter->writeAttribute('val', "$ruleValue");
|
||||
}
|
||||
}
|
||||
|
||||
$objWriter->endElement();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,166 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class AutoFilterAverageTop10Test extends SetupTeardown
|
||||
{
|
||||
public function initsheet(): Worksheet
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getCell('A1')->setValue('Header');
|
||||
$sheet->getCell('A2')->setValue(1);
|
||||
$sheet->getCell('A3')->setValue(3);
|
||||
$sheet->getCell('A4')->setValue(5);
|
||||
$sheet->getCell('A5')->setValue(7);
|
||||
$sheet->getCell('A6')->setValue(9);
|
||||
$sheet->getCell('A7')->setValue(2);
|
||||
$sheet->getCell('A8')->setValue(4);
|
||||
$sheet->getCell('A9')->setValue(6);
|
||||
$sheet->getCell('A10')->setValue(8);
|
||||
$this->maxRow = 10;
|
||||
|
||||
return $sheet;
|
||||
}
|
||||
|
||||
public function providerAverage(): array
|
||||
{
|
||||
return [
|
||||
[[5, 6, 9, 10], Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE],
|
||||
[[2, 3, 7, 8], Rule::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerAverage
|
||||
*/
|
||||
public function testAboveAverage(array $expectedVisible, string $rule): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$maxRow = $this->maxRow;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
'',
|
||||
$rule
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER);
|
||||
|
||||
self::assertEquals($expectedVisible, $this->getVisible());
|
||||
}
|
||||
|
||||
public function providerTop10(): array
|
||||
{
|
||||
return [
|
||||
[[6, 10], Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP, 2],
|
||||
[[2, 3, 7], Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM, 3],
|
||||
[[6], Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT, Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP, 10],
|
||||
[[2, 3, 7], Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT, Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM, 40],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTop10
|
||||
*/
|
||||
public function testTop10(array $expectedVisible, string $rule, string $ruleType, int $count): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$maxRow = $this->maxRow;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
$rule,
|
||||
$count,
|
||||
$ruleType
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_TOPTENFILTER);
|
||||
|
||||
self::assertEquals($expectedVisible, $this->getVisible());
|
||||
}
|
||||
|
||||
public function initsheetTies(): Worksheet
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getCell('A1')->setValue('Header');
|
||||
$sheet->getCell('A2')->setValue(1);
|
||||
$sheet->getCell('A3')->setValue(3);
|
||||
$sheet->getCell('A4')->setValue(3);
|
||||
$sheet->getCell('A5')->setValue(7);
|
||||
$sheet->getCell('A6')->setValue(9);
|
||||
$sheet->getCell('A7')->setValue(4);
|
||||
$sheet->getCell('A8')->setValue(4);
|
||||
$sheet->getCell('A9')->setValue(8);
|
||||
$sheet->getCell('A10')->setValue(8);
|
||||
$this->maxRow = 10;
|
||||
|
||||
return $sheet;
|
||||
}
|
||||
|
||||
public function providerTop10Ties(): array
|
||||
{
|
||||
return [
|
||||
[[2, 3, 4], Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM, 2],
|
||||
[[2], Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM, 1],
|
||||
[[5, 6, 7, 8, 9, 10], Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP, 5],
|
||||
[[6], Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP, 1],
|
||||
[[2, 3, 4], Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT, Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM, 25],
|
||||
[[6, 9, 10], Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT, Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP, 25],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTop10Ties
|
||||
*/
|
||||
public function testTop10Ties(array $expectedVisible, string $rule, string $ruleType, int $count): void
|
||||
{
|
||||
$sheet = $this->initSheetTies();
|
||||
$maxRow = $this->maxRow;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
$rule,
|
||||
$count,
|
||||
$ruleType
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_TOPTENFILTER);
|
||||
|
||||
self::assertEquals($expectedVisible, $this->getVisible());
|
||||
}
|
||||
|
||||
public function testTop10Exceeds500(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getCell('A1')->setValue('Heading');
|
||||
for ($row = 2; $row < 602; ++$row) {
|
||||
$sheet->getCell("A$row")->setValue($row);
|
||||
}
|
||||
$maxRow = $this->maxRow = 601;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE,
|
||||
550,
|
||||
Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_TOPTENFILTER);
|
||||
|
||||
$visible = $this->getVisible();
|
||||
self::assertCount(500, $this->getVisible(), 'Top10 Filter limited to 500 items plus ties');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class AutoFilterCustomTextTest extends SetupTeardown
|
||||
{
|
||||
public function initsheet(): Worksheet
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getCell('A1')->setValue('Header');
|
||||
$sheet->getCell('A2')->setValue('abc');
|
||||
$sheet->getCell('A3')->setValue('cba');
|
||||
$sheet->getCell('A4')->setValue('cab');
|
||||
// nothing in cell A5
|
||||
$sheet->getCell('A6')->setValue('c*b');
|
||||
$sheet->getCell('A7')->setValue('c?b');
|
||||
$sheet->getCell('A8')->setValue('a');
|
||||
$sheet->getCell('A9')->setValue('zzbc');
|
||||
$sheet->getCell('A10')->setValue('zzbcd');
|
||||
$sheet->getCell('A11')->setValue('~pqr');
|
||||
$sheet->getCell('A12')->setValue('pqr~');
|
||||
$this->maxRow = 12;
|
||||
|
||||
return $sheet;
|
||||
}
|
||||
|
||||
public function providerCustomText(): array
|
||||
{
|
||||
return [
|
||||
'begins with a' => [[2, 8], 'a*'],
|
||||
'ends with b' => [[4, 6, 7], '*b'],
|
||||
'contains c' => [[2, 3, 4, 6, 7, 9, 10], '*c*'],
|
||||
'empty' => [[5], ''],
|
||||
'contains asterisk' => [[6], '*~**'],
|
||||
'contains question mark' => [[7], '*~?*'],
|
||||
'c followed by character followed by b' => [[4, 6, 7], 'c?b'],
|
||||
'one character followed by bc' => [[2], '?bc'],
|
||||
'two characters followed by bc' => [[9], '??bc'],
|
||||
'starts with z ends with c' => [[9], 'z*c'],
|
||||
'starts with tilde' => [[11], '~~*'],
|
||||
'contains tilde' => [[11, 12], '*~~*'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCustomText
|
||||
*/
|
||||
public function testCustomTest(array $expectedVisible, string $pattern): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$maxRow = $this->maxRow;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
$pattern
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
|
||||
|
||||
self::assertEquals($expectedVisible, $this->getVisible());
|
||||
}
|
||||
|
||||
public function testCustomTestNotEqual(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$maxRow = $this->maxRow;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL,
|
||||
''
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
|
||||
|
||||
self::assertEquals([2, 3, 4, 6, 7, 8, 9, 10, 11, 12], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testCustomTestGreaterThan(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$maxRow = $this->maxRow;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN,
|
||||
''
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
|
||||
|
||||
self::assertEquals([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], $this->getVisible());
|
||||
}
|
||||
}
|
||||
|
|
@ -3,13 +3,11 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AutoFilterMonthTest extends TestCase
|
||||
class AutoFilterMonthTest extends SetupTeardown
|
||||
{
|
||||
public function providerMonth(): array
|
||||
{
|
||||
|
|
@ -20,7 +18,7 @@ class AutoFilterMonthTest extends TestCase
|
|||
];
|
||||
}
|
||||
|
||||
private static function setCells(Worksheet $sheet, int $startMonth): void
|
||||
private function setCells(Worksheet $sheet, int $startMonth): void
|
||||
{
|
||||
$sheet->getCell('A1')->setValue('Date');
|
||||
$sheet->getCell('A2')->setValue('=TODAY()');
|
||||
|
|
@ -47,6 +45,7 @@ class AutoFilterMonthTest extends TestCase
|
|||
}
|
||||
$sheet->getCell('A8')->setValue('=DATE(YEAR(A2) + 1, MONTH(A2), 1)');
|
||||
$sheet->getCell('A9')->setValue('=DATE(YEAR(A2) - 1, MONTH(A2), 1)');
|
||||
$this->maxRow = 9;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -57,15 +56,14 @@ class AutoFilterMonthTest extends TestCase
|
|||
// Loop to avoid rare edge case where first calculation
|
||||
// and second do not take place in same day.
|
||||
do {
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet = $this->getSheet();
|
||||
$dtStart = new DateTimeImmutable();
|
||||
$startDay = (int) $dtStart->format('d');
|
||||
$startMonth = (int) $dtStart->format('m');
|
||||
self::setCells($sheet, $startMonth);
|
||||
$this->setCells($sheet, $startMonth);
|
||||
|
||||
$maxRow = 9;
|
||||
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter();
|
||||
$maxRow = $this->maxRow;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
|
||||
|
|
@ -80,12 +78,7 @@ class AutoFilterMonthTest extends TestCase
|
|||
$dtEnd = new DateTimeImmutable();
|
||||
$endDay = (int) $dtEnd->format('d');
|
||||
} while ($startDay !== $endDay);
|
||||
$actualVisible = [];
|
||||
for ($row = 2; $row <= $maxRow; ++$row) {
|
||||
if ($sheet->getRowDimension($row)->getVisible()) {
|
||||
$actualVisible[] = $row;
|
||||
}
|
||||
}
|
||||
self::assertEquals($expectedVisible, $actualVisible);
|
||||
|
||||
self::assertEquals($expectedVisible, $this->getVisible());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,10 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AutoFilterQuarterTest extends TestCase
|
||||
class AutoFilterQuarterTest extends SetupTeardown
|
||||
{
|
||||
public function providerQuarter(): array
|
||||
{
|
||||
|
|
@ -20,8 +17,9 @@ class AutoFilterQuarterTest extends TestCase
|
|||
];
|
||||
}
|
||||
|
||||
private static function setCells(Worksheet $sheet): void
|
||||
private function setCells(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getCell('A1')->setValue('Date');
|
||||
$sheet->getCell('A2')->setValue('=TODAY()');
|
||||
$sheet->getCell('A3')->setValue('=DATE(YEAR(A2), MONTH(A2), 1)');
|
||||
|
|
@ -31,6 +29,7 @@ class AutoFilterQuarterTest extends TestCase
|
|||
$sheet->getCell('A7')->setValue('=DATE(YEAR(A2), MONTH(A2) - 6, 1)');
|
||||
$sheet->getCell('A8')->setValue('=DATE(YEAR(A2) + 1, MONTH(A2), 1)');
|
||||
$sheet->getCell('A9')->setValue('=DATE(YEAR(A2) - 1, MONTH(A2), 1)');
|
||||
$this->maxRow = 9;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -41,14 +40,13 @@ class AutoFilterQuarterTest extends TestCase
|
|||
// Loop to avoid rare edge case where first calculation
|
||||
// and second do not take place in same day.
|
||||
do {
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet = $this->getSheet();
|
||||
$dtStart = new DateTimeImmutable();
|
||||
$startDay = (int) $dtStart->format('d');
|
||||
self::setCells($sheet);
|
||||
$this->setCells();
|
||||
|
||||
$maxRow = 9;
|
||||
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter();
|
||||
$maxRow = $this->maxRow;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
|
||||
|
|
@ -63,12 +61,7 @@ class AutoFilterQuarterTest extends TestCase
|
|||
$dtEnd = new DateTimeImmutable();
|
||||
$endDay = (int) $dtEnd->format('d');
|
||||
} while ($startDay !== $endDay);
|
||||
$actualVisible = [];
|
||||
for ($row = 2; $row <= $maxRow; ++$row) {
|
||||
if ($sheet->getRowDimension($row)->getVisible()) {
|
||||
$actualVisible[] = $row;
|
||||
}
|
||||
}
|
||||
self::assertEquals($expectedVisible, $actualVisible);
|
||||
|
||||
self::assertEquals($expectedVisible, $this->getVisible());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,95 +2,78 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Collection\Cells;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AutoFilterTest extends TestCase
|
||||
class AutoFilterTest extends SetupTeardown
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $testInitialRange = 'H2:O256';
|
||||
|
||||
/**
|
||||
* @var AutoFilter
|
||||
*/
|
||||
private $testAutoFilterObject;
|
||||
|
||||
/**
|
||||
* @var Worksheet&MockObject
|
||||
*/
|
||||
private $mockWorksheetObject;
|
||||
|
||||
/**
|
||||
* @var Cells&MockObject
|
||||
*/
|
||||
private $cellCollection;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->mockWorksheetObject = $this->getMockBuilder(Worksheet::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->cellCollection = $this->getMockBuilder(Cells::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->mockWorksheetObject->expects(self::any())
|
||||
->method('getCellCollection')
|
||||
->willReturn($this->cellCollection);
|
||||
|
||||
$this->testAutoFilterObject = new AutoFilter($this->testInitialRange, $this->mockWorksheetObject);
|
||||
}
|
||||
private const INITIAL_RANGE = 'H2:O256';
|
||||
|
||||
public function testToString(): void
|
||||
{
|
||||
$expectedResult = $this->testInitialRange;
|
||||
$expectedResult = self::INITIAL_RANGE;
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
// magic __toString should return the active autofilter range
|
||||
$result = $this->testAutoFilterObject;
|
||||
$result = (string) $autoFilter;
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function testGetParent(): void
|
||||
{
|
||||
$result = $this->testAutoFilterObject->getParent();
|
||||
self::assertInstanceOf(Worksheet::class, $result);
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
$result = $autoFilter->getParent();
|
||||
self::assertSame($sheet, $result);
|
||||
}
|
||||
|
||||
public function testSetParent(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
$spreadsheet = $this->getSpreadsheet();
|
||||
$sheet2 = $spreadsheet->createSheet();
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterObject->setParent($this->mockWorksheetObject);
|
||||
$result = $autoFilter->setParent($sheet2);
|
||||
self::assertInstanceOf(AutoFilter::class, $result);
|
||||
}
|
||||
|
||||
public function testGetRange(): void
|
||||
{
|
||||
$expectedResult = $this->testInitialRange;
|
||||
$expectedResult = self::INITIAL_RANGE;
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
// Result should be the active autofilter range
|
||||
$result = $this->testAutoFilterObject->getRange();
|
||||
$result = $autoFilter->getRange();
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function testSetRange(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$title = $sheet->getTitle();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
$ranges = [
|
||||
'G1:J512' => 'Worksheet1!G1:J512',
|
||||
'G1:J512' => "$title!G1:J512",
|
||||
'K1:N20' => 'K1:N20',
|
||||
];
|
||||
|
||||
foreach ($ranges as $actualRange => $fullRange) {
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterObject->setRange($fullRange);
|
||||
$result = $autoFilter->setRange($fullRange);
|
||||
self::assertInstanceOf(AutoFilter::class, $result);
|
||||
|
||||
// Result should be the new autofilter range
|
||||
$result = $this->testAutoFilterObject->getRange();
|
||||
$result = $autoFilter->getRange();
|
||||
self::assertEquals($actualRange, $result);
|
||||
}
|
||||
}
|
||||
|
|
@ -98,29 +81,36 @@ class AutoFilterTest extends TestCase
|
|||
public function testClearRange(): void
|
||||
{
|
||||
$expectedResult = '';
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterObject->setRange('');
|
||||
$result = $autoFilter->setRange('');
|
||||
self::assertInstanceOf(AutoFilter::class, $result);
|
||||
|
||||
// Result should be a clear range
|
||||
$result = $this->testAutoFilterObject->getRange();
|
||||
$result = $autoFilter->getRange();
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function testSetRangeInvalidRange(): void
|
||||
{
|
||||
$this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class);
|
||||
$this->expectException(PhpSpreadsheetException::class);
|
||||
|
||||
$expectedResult = 'A1';
|
||||
|
||||
$this->testAutoFilterObject->setRange($expectedResult);
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange($expectedResult);
|
||||
}
|
||||
|
||||
public function testGetColumnsEmpty(): void
|
||||
{
|
||||
// There should be no columns yet defined
|
||||
$result = $this->testAutoFilterObject->getColumns();
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$result = $autoFilter->getColumns();
|
||||
self::assertIsArray($result);
|
||||
self::assertCount(0, $result);
|
||||
}
|
||||
|
|
@ -132,33 +122,42 @@ class AutoFilterTest extends TestCase
|
|||
'K' => 3,
|
||||
'M' => 5,
|
||||
];
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
// 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);
|
||||
$result = $autoFilter->getColumnOffset($columnIndex);
|
||||
self::assertEquals($columnOffset, $result);
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetInvalidColumnOffset(): void
|
||||
{
|
||||
$this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class);
|
||||
$this->expectException(PhpSpreadsheetException::class);
|
||||
|
||||
$invalidColumn = 'G';
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
$this->testAutoFilterObject->getColumnOffset($invalidColumn);
|
||||
$autoFilter->getColumnOffset($invalidColumn);
|
||||
}
|
||||
|
||||
public function testSetColumnWithString(): void
|
||||
{
|
||||
$expectedResult = 'L';
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterObject->setColumn($expectedResult);
|
||||
$result = $autoFilter->setColumn($expectedResult);
|
||||
self::assertInstanceOf(AutoFilter::class, $result);
|
||||
|
||||
$result = $this->testAutoFilterObject->getColumns();
|
||||
$result = $autoFilter->getColumns();
|
||||
// Result should be an array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column
|
||||
// objects for each column we set indexed by the column ID
|
||||
self::assertIsArray($result);
|
||||
|
|
@ -169,23 +168,29 @@ class AutoFilterTest extends TestCase
|
|||
|
||||
public function testSetInvalidColumnWithString(): void
|
||||
{
|
||||
$this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class);
|
||||
$this->expectException(PhpSpreadsheetException::class);
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
$invalidColumn = 'A';
|
||||
|
||||
$this->testAutoFilterObject->setColumn($invalidColumn);
|
||||
$autoFilter->setColumn($invalidColumn);
|
||||
}
|
||||
|
||||
public function testSetColumnWithColumnObject(): void
|
||||
{
|
||||
$expectedResult = 'M';
|
||||
$columnObject = new AutoFilter\Column($expectedResult);
|
||||
$columnObject = new Column($expectedResult);
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterObject->setColumn($columnObject);
|
||||
$result = $autoFilter->setColumn($columnObject);
|
||||
self::assertInstanceOf(AutoFilter::class, $result);
|
||||
|
||||
$result = $this->testAutoFilterObject->getColumns();
|
||||
$result = $autoFilter->getColumns();
|
||||
// Result should be an array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column
|
||||
// objects for each column we set indexed by the column ID
|
||||
self::assertIsArray($result);
|
||||
|
|
@ -196,30 +201,40 @@ class AutoFilterTest extends TestCase
|
|||
|
||||
public function testSetInvalidColumnWithObject(): void
|
||||
{
|
||||
$this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class);
|
||||
$this->expectException(PhpSpreadsheetException::class);
|
||||
|
||||
$invalidColumn = 'E';
|
||||
$this->testAutoFilterObject->setColumn($invalidColumn);
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
$autoFilter->setColumn($invalidColumn);
|
||||
}
|
||||
|
||||
public function testSetColumnWithInvalidDataType(): void
|
||||
{
|
||||
$this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class);
|
||||
$this->expectException(PhpSpreadsheetException::class);
|
||||
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
$invalidColumn = 123.456;
|
||||
// @phpstan-ignore-next-line
|
||||
$this->testAutoFilterObject->setColumn($invalidColumn);
|
||||
$autoFilter->setColumn($invalidColumn);
|
||||
}
|
||||
|
||||
public function testGetColumns(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
$columnIndexes = ['L', 'M'];
|
||||
|
||||
foreach ($columnIndexes as $columnIndex) {
|
||||
$this->testAutoFilterObject->setColumn($columnIndex);
|
||||
$autoFilter->setColumn($columnIndex);
|
||||
}
|
||||
|
||||
$result = $this->testAutoFilterObject->getColumns();
|
||||
$result = $autoFilter->getColumns();
|
||||
// Result should be an array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column
|
||||
// objects for each column we set indexed by the column ID
|
||||
self::assertIsArray($result);
|
||||
|
|
@ -228,26 +243,38 @@ class AutoFilterTest extends TestCase
|
|||
self::assertArrayHasKey($columnIndex, $result);
|
||||
self::assertInstanceOf(Column::class, $result[$columnIndex]);
|
||||
}
|
||||
|
||||
$autoFilter->setRange('');
|
||||
self::assertCount(0, $autoFilter->getColumns());
|
||||
self::assertSame('', $autoFilter->getRange());
|
||||
}
|
||||
|
||||
public function testGetColumn(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
$columnIndexes = ['L', 'M'];
|
||||
|
||||
foreach ($columnIndexes as $columnIndex) {
|
||||
$this->testAutoFilterObject->setColumn($columnIndex);
|
||||
$autoFilter->setColumn($columnIndex);
|
||||
}
|
||||
|
||||
// If we request a specific column by its column ID, we should
|
||||
// get a \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column object returned
|
||||
foreach ($columnIndexes as $columnIndex) {
|
||||
$result = $this->testAutoFilterObject->getColumn($columnIndex);
|
||||
$result = $autoFilter->getColumn($columnIndex);
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetColumnByOffset(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
$columnIndexes = [
|
||||
0 => 'H',
|
||||
3 => 'K',
|
||||
|
|
@ -257,7 +284,7 @@ class AutoFilterTest extends TestCase
|
|||
// If we request a specific column by its offset, we should
|
||||
// get a \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column object returned
|
||||
foreach ($columnIndexes as $columnIndex => $columnID) {
|
||||
$result = $this->testAutoFilterObject->getColumnByOffset($columnIndex);
|
||||
$result = $autoFilter->getColumnByOffset($columnIndex);
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
self::assertEquals($result->getColumnIndex(), $columnID);
|
||||
}
|
||||
|
|
@ -265,83 +292,152 @@ class AutoFilterTest extends TestCase
|
|||
|
||||
public function testGetColumnIfNotSet(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
// If we request a specific column by its column ID, we should
|
||||
// get a \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column object returned
|
||||
$result = $this->testAutoFilterObject->getColumn('K');
|
||||
$result = $autoFilter->getColumn('K');
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
}
|
||||
|
||||
public function testGetColumnWithoutRangeSet(): void
|
||||
{
|
||||
$this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class);
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
|
||||
// Clear the range
|
||||
$this->testAutoFilterObject->setRange('');
|
||||
$this->testAutoFilterObject->getColumn('A');
|
||||
$autoFilter->setRange('');
|
||||
$autoFilter->getColumn('A');
|
||||
}
|
||||
|
||||
public function testClearRangeWithExistingColumns(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
$expectedResult = '';
|
||||
|
||||
$columnIndexes = ['L', 'M', 'N'];
|
||||
foreach ($columnIndexes as $columnIndex) {
|
||||
$this->testAutoFilterObject->setColumn($columnIndex);
|
||||
$autoFilter->setColumn($columnIndex);
|
||||
}
|
||||
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterObject->setRange('');
|
||||
$result = $autoFilter->setRange('');
|
||||
self::assertInstanceOf(AutoFilter::class, $result);
|
||||
|
||||
// Range should be cleared
|
||||
$result = $this->testAutoFilterObject->getRange();
|
||||
$result = $autoFilter->getRange();
|
||||
self::assertEquals($expectedResult, $result);
|
||||
|
||||
// Column array should be cleared
|
||||
$result = $this->testAutoFilterObject->getColumns();
|
||||
$result = $autoFilter->getColumns();
|
||||
self::assertIsArray($result);
|
||||
self::assertCount(0, $result);
|
||||
}
|
||||
|
||||
public function testSetRangeWithExistingColumns(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
$expectedResult = 'G1:J512';
|
||||
|
||||
// These columns should be retained
|
||||
$columnIndexes1 = ['I', 'J'];
|
||||
foreach ($columnIndexes1 as $columnIndex) {
|
||||
$this->testAutoFilterObject->setColumn($columnIndex);
|
||||
$autoFilter->setColumn($columnIndex);
|
||||
}
|
||||
// These columns should be discarded
|
||||
$columnIndexes2 = ['K', 'L', 'M'];
|
||||
foreach ($columnIndexes2 as $columnIndex) {
|
||||
$this->testAutoFilterObject->setColumn($columnIndex);
|
||||
$autoFilter->setColumn($columnIndex);
|
||||
}
|
||||
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterObject->setRange($expectedResult);
|
||||
$result = $autoFilter->setRange($expectedResult);
|
||||
self::assertInstanceOf(AutoFilter::class, $result);
|
||||
|
||||
// Range should be correctly set
|
||||
$result = $this->testAutoFilterObject->getRange();
|
||||
$result = $autoFilter->getRange();
|
||||
self::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();
|
||||
$result = $autoFilter->getColumns();
|
||||
self::assertIsArray($result);
|
||||
self::assertCount(count($columnIndexes1), $result);
|
||||
}
|
||||
|
||||
public function testClone(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
$columnIndexes = ['L', 'M'];
|
||||
|
||||
foreach ($columnIndexes as $columnIndex) {
|
||||
$this->testAutoFilterObject->setColumn($columnIndex);
|
||||
$autoFilter->setColumn($columnIndex);
|
||||
}
|
||||
|
||||
$result = clone $this->testAutoFilterObject;
|
||||
$result = clone $autoFilter;
|
||||
self::assertInstanceOf(AutoFilter::class, $result);
|
||||
self::assertSame($autoFilter->getRange(), $result->getRange());
|
||||
self::assertNull($result->getParent());
|
||||
self::assertNotNull($autoFilter->getParent());
|
||||
self::assertInstanceOf(Worksheet::class, $autoFilter->getParent());
|
||||
$autoColumns = $autoFilter->getColumns();
|
||||
$resultColumns = $result->getColumns();
|
||||
self::assertIsArray($autoColumns);
|
||||
self::assertIsArray($resultColumns);
|
||||
self::assertCount(2, $autoColumns);
|
||||
self::assertCount(2, $resultColumns);
|
||||
self::assertArrayHasKey('L', $autoColumns);
|
||||
self::assertArrayHasKey('L', $resultColumns);
|
||||
self::assertArrayHasKey('M', $autoColumns);
|
||||
self::assertArrayHasKey('M', $resultColumns);
|
||||
self::assertInstanceOf(Column::class, $autoColumns['L']);
|
||||
self::assertInstanceOf(Column::class, $resultColumns['L']);
|
||||
self::assertInstanceOf(Column::class, $autoColumns['M']);
|
||||
self::assertInstanceOf(Column::class, $resultColumns['M']);
|
||||
}
|
||||
|
||||
public function testNoWorksheet(): void
|
||||
{
|
||||
$autoFilter = new AutoFilter();
|
||||
self::assertSame($autoFilter, $autoFilter->showHideRows());
|
||||
}
|
||||
|
||||
public function testClearColumn(): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange(self::INITIAL_RANGE);
|
||||
$columnIndexes = ['J', 'K', 'L', 'M'];
|
||||
|
||||
foreach ($columnIndexes as $columnIndex) {
|
||||
$autoFilter->setColumn($columnIndex);
|
||||
}
|
||||
$columns = $autoFilter->getColumns();
|
||||
self::assertCount(4, $columns);
|
||||
self::assertArrayHasKey('J', $columns);
|
||||
self::assertArrayHasKey('K', $columns);
|
||||
self::assertArrayHasKey('L', $columns);
|
||||
self::assertArrayHasKey('M', $columns);
|
||||
$autoFilter->clearColumn('K');
|
||||
$columns = $autoFilter->getColumns();
|
||||
self::assertCount(3, $columns);
|
||||
self::assertArrayHasKey('J', $columns);
|
||||
self::assertArrayHasKey('L', $columns);
|
||||
self::assertArrayHasKey('M', $columns);
|
||||
$autoFilter->shiftColumn('L', 'K');
|
||||
$columns = $autoFilter->getColumns();
|
||||
self::assertCount(3, $columns);
|
||||
self::assertArrayHasKey('J', $columns);
|
||||
self::assertArrayHasKey('K', $columns);
|
||||
self::assertArrayHasKey('M', $columns);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,10 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AutoFilterTodayTest extends TestCase
|
||||
class AutoFilterTodayTest extends SetupTeardown
|
||||
{
|
||||
public function providerYesterdayTodayTomorrow(): array
|
||||
{
|
||||
|
|
@ -27,8 +25,7 @@ class AutoFilterTodayTest extends TestCase
|
|||
// Loop to avoid rare edge case where first calculation
|
||||
// and second do not take place in same day.
|
||||
do {
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet = $this->getSheet();
|
||||
$dtStart = new DateTimeImmutable();
|
||||
$startDay = $dtStart->format('d');
|
||||
$sheet->getCell('A1')->setValue('Date');
|
||||
|
|
@ -38,8 +35,8 @@ class AutoFilterTodayTest extends TestCase
|
|||
$sheet->getCell('A5')->setValue('=TODAY()');
|
||||
$sheet->getCell('A6')->setValue('=A5+1');
|
||||
$sheet->getCell('A7')->setValue('=A5-1');
|
||||
$maxRow = 7;
|
||||
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter();
|
||||
$this->maxRow = $maxRow = 7;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
|
||||
|
|
@ -54,12 +51,7 @@ class AutoFilterTodayTest extends TestCase
|
|||
$dtEnd = new DateTimeImmutable();
|
||||
$endDay = $dtEnd->format('d');
|
||||
} while ($startDay !== $endDay);
|
||||
$actualVisible = [];
|
||||
for ($row = 2; $row <= $maxRow; ++$row) {
|
||||
if ($sheet->getRowDimension($row)->getVisible()) {
|
||||
$actualVisible[] = $row;
|
||||
}
|
||||
}
|
||||
self::assertEquals($expectedVisible, $actualVisible);
|
||||
|
||||
self::assertEquals($expectedVisible, $this->getVisible());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,11 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AutoFilterWeekTest extends TestCase
|
||||
class AutoFilterWeekTest extends SetupTeardown
|
||||
{
|
||||
public function providerWeek(): array
|
||||
{
|
||||
|
|
@ -20,8 +18,9 @@ class AutoFilterWeekTest extends TestCase
|
|||
];
|
||||
}
|
||||
|
||||
private static function setCells(Worksheet $sheet): void
|
||||
private function setCells(Worksheet $sheet): void
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getCell('A1')->setValue('Date');
|
||||
$sheet->getCell('A2')->setValue('=TODAY()');
|
||||
$sheet->getCell('B2')->setValue('=WEEKDAY(A2) - 1'); // subtract to get to Sunday
|
||||
|
|
@ -32,6 +31,7 @@ class AutoFilterWeekTest extends TestCase
|
|||
$sheet->getCell('A7')->setValue('=DATE(YEAR(A3), MONTH(A3), DAY(A3) - 12)');
|
||||
$sheet->getCell('A8')->setValue('=DATE(YEAR(A2) + 1, MONTH(A2), 1)');
|
||||
$sheet->getCell('A9')->setValue('=DATE(YEAR(A2) - 1, MONTH(A2), 1)');
|
||||
$this->maxRow = 9;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -42,14 +42,13 @@ class AutoFilterWeekTest extends TestCase
|
|||
// Loop to avoid rare edge case where first calculation
|
||||
// and second do not take place in same day.
|
||||
do {
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet = $this->getSheet();
|
||||
$dtStart = new DateTimeImmutable();
|
||||
$startDay = (int) $dtStart->format('d');
|
||||
self::setCells($sheet);
|
||||
|
||||
$maxRow = 9;
|
||||
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter();
|
||||
$maxRow = $this->maxRow;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
|
||||
|
|
@ -64,12 +63,7 @@ class AutoFilterWeekTest extends TestCase
|
|||
$dtEnd = new DateTimeImmutable();
|
||||
$endDay = (int) $dtEnd->format('d');
|
||||
} while ($startDay !== $endDay);
|
||||
$actualVisible = [];
|
||||
for ($row = 2; $row <= $maxRow; ++$row) {
|
||||
if ($sheet->getRowDimension($row)->getVisible()) {
|
||||
$actualVisible[] = $row;
|
||||
}
|
||||
}
|
||||
self::assertEquals($expectedVisible, $actualVisible);
|
||||
|
||||
self::assertEquals($expectedVisible, $this->getVisible());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,10 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AutoFilterYearTest extends TestCase
|
||||
class AutoFilterYearTest extends SetupTeardown
|
||||
{
|
||||
public function providerYear(): array
|
||||
{
|
||||
|
|
@ -30,8 +28,7 @@ class AutoFilterYearTest extends TestCase
|
|||
// Loop to avoid rare edge case where first calculation
|
||||
// and second do not take place in same day.
|
||||
do {
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet = $this->getSheet();
|
||||
$dtStart = new DateTimeImmutable();
|
||||
$startDay = (int) $dtStart->format('d');
|
||||
$sheet->getCell('A1')->setValue('Date');
|
||||
|
|
@ -48,8 +45,9 @@ class AutoFilterYearTest extends TestCase
|
|||
}
|
||||
++$row;
|
||||
$sheet->getCell("A$row")->setValue('=DATE(2041, 1, 1)'); // beyond epoch
|
||||
$maxRow = $row;
|
||||
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter();
|
||||
++$row; // empty row at end
|
||||
$this->maxRow = $maxRow = $row;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
|
||||
|
|
@ -64,13 +62,8 @@ class AutoFilterYearTest extends TestCase
|
|||
$dtEnd = new DateTimeImmutable();
|
||||
$endDay = (int) $dtEnd->format('d');
|
||||
} while ($startDay !== $endDay);
|
||||
$actualVisible = [];
|
||||
for ($row = 2; $row <= $maxRow; ++$row) {
|
||||
if ($sheet->getRowDimension($row)->getVisible()) {
|
||||
$actualVisible[] = $row;
|
||||
}
|
||||
}
|
||||
self::assertEquals($expectedVisible, $actualVisible);
|
||||
|
||||
self::assertEquals($expectedVisible, $this->getVisible());
|
||||
}
|
||||
|
||||
public function testYearToDate(): void
|
||||
|
|
@ -78,8 +71,7 @@ class AutoFilterYearTest extends TestCase
|
|||
// Loop to avoid rare edge case where first calculation
|
||||
// and second do not take place in same day.
|
||||
do {
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet = $this->getSheet();
|
||||
$dtStart = new DateTimeImmutable();
|
||||
$startDay = (int) $dtStart->format('d');
|
||||
$startMonth = (int) $dtStart->format('m');
|
||||
|
|
@ -90,8 +82,8 @@ class AutoFilterYearTest extends TestCase
|
|||
$sheet->getCell('A5')->setValue('=DATE(YEAR(A2), 1, 1)');
|
||||
$sheet->getCell('A6')->setValue('=A5 - 1');
|
||||
|
||||
$maxRow = 6;
|
||||
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter();
|
||||
$this->maxRow = $maxRow = 6;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:A$maxRow");
|
||||
$columnFilter = $autoFilter->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
|
||||
|
|
@ -106,13 +98,8 @@ class AutoFilterYearTest extends TestCase
|
|||
$dtEnd = new DateTimeImmutable();
|
||||
$endDay = (int) $dtEnd->format('d');
|
||||
} while ($startDay !== $endDay);
|
||||
$actualVisible = [];
|
||||
for ($row = 2; $row <= $maxRow; ++$row) {
|
||||
if ($sheet->getRowDimension($row)->getVisible()) {
|
||||
$actualVisible[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
$expected = ($startMonth === 12 && $startDay === 31) ? [2, 3, 5] : [2, 5];
|
||||
self::assertEquals($expected, $actualVisible);
|
||||
self::assertEquals($expected, $this->getVisible());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,111 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter\Column;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RuleTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Rule
|
||||
*/
|
||||
private $testAutoFilterRuleObject;
|
||||
|
||||
/**
|
||||
* @var Column&MockObject
|
||||
*/
|
||||
private $mockAutoFilterColumnObject;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->mockAutoFilterColumnObject = $this->getMockBuilder(Column::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->testAutoFilterRuleObject = new Rule(
|
||||
$this->mockAutoFilterColumnObject
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetRuleType(): void
|
||||
{
|
||||
$result = $this->testAutoFilterRuleObject->getRuleType();
|
||||
self::assertEquals(Rule::AUTOFILTER_RULETYPE_FILTER, $result);
|
||||
}
|
||||
|
||||
public function testSetRuleType(): void
|
||||
{
|
||||
$expectedResult = Rule::AUTOFILTER_RULETYPE_DATEGROUP;
|
||||
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterRuleObject->setRuleType($expectedResult);
|
||||
self::assertInstanceOf(Rule::class, $result);
|
||||
|
||||
$result = $this->testAutoFilterRuleObject->getRuleType();
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function testSetValue(): void
|
||||
{
|
||||
$expectedResult = 100;
|
||||
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterRuleObject->setValue($expectedResult);
|
||||
self::assertInstanceOf(Rule::class, $result);
|
||||
|
||||
$result = $this->testAutoFilterRuleObject->getValue();
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function testGetOperator(): void
|
||||
{
|
||||
$result = $this->testAutoFilterRuleObject->getOperator();
|
||||
self::assertEquals(Rule::AUTOFILTER_COLUMN_RULE_EQUAL, $result);
|
||||
}
|
||||
|
||||
public function testSetOperator(): void
|
||||
{
|
||||
$expectedResult = Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN;
|
||||
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterRuleObject->setOperator($expectedResult);
|
||||
self::assertInstanceOf(Rule::class, $result);
|
||||
|
||||
$result = $this->testAutoFilterRuleObject->getOperator();
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function testSetGrouping(): void
|
||||
{
|
||||
$expectedResult = Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH;
|
||||
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterRuleObject->setGrouping($expectedResult);
|
||||
self::assertInstanceOf(Rule::class, $result);
|
||||
|
||||
$result = $this->testAutoFilterRuleObject->getGrouping();
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function testGetParent(): void
|
||||
{
|
||||
$result = $this->testAutoFilterRuleObject->getParent();
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
}
|
||||
|
||||
public function testSetParent(): void
|
||||
{
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterRuleObject->setParent($this->mockAutoFilterColumnObject);
|
||||
self::assertInstanceOf(Rule::class, $result);
|
||||
}
|
||||
|
||||
public function testClone(): void
|
||||
{
|
||||
$result = clone $this->testAutoFilterRuleObject;
|
||||
self::assertInstanceOf(Rule::class, $result);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,148 +2,177 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class ColumnTest extends TestCase
|
||||
class ColumnTest extends SetupTeardown
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $testInitialColumn = 'H';
|
||||
|
||||
/**
|
||||
* @var Column
|
||||
*/
|
||||
private $testAutoFilterColumnObject;
|
||||
|
||||
/**
|
||||
* @var AutoFilter&MockObject
|
||||
*/
|
||||
private $mockAutoFilterObject;
|
||||
|
||||
protected function setUp(): void
|
||||
protected function initSheet(): Worksheet
|
||||
{
|
||||
$this->mockAutoFilterObject = $this->getMockBuilder(AutoFilter::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getCell('G1')->setValue('Heading');
|
||||
$sheet->getCell('G2')->setValue(2);
|
||||
$sheet->getCell('G3')->setValue(3);
|
||||
$sheet->getCell('G4')->setValue(4);
|
||||
$sheet->getCell('H1')->setValue('Heading2');
|
||||
$sheet->getCell('H2')->setValue(1);
|
||||
$sheet->getCell('H3')->setValue(2);
|
||||
$sheet->getCell('H4')->setValue(3);
|
||||
$this->maxRow = $maxRow = 4;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("G1:H$maxRow");
|
||||
|
||||
$this->mockAutoFilterObject->expects(self::any())
|
||||
->method('testColumnInRange')
|
||||
->willReturn(3);
|
||||
|
||||
$this->testAutoFilterColumnObject = new Column($this->testInitialColumn, $this->mockAutoFilterObject);
|
||||
return $sheet;
|
||||
}
|
||||
|
||||
public function testGetColumnIndex(): void
|
||||
public function testVariousGets(): void
|
||||
{
|
||||
$result = $this->testAutoFilterColumnObject->getColumnIndex();
|
||||
self::assertEquals($this->testInitialColumn, $result);
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('H');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
$result = $columnFilter->getColumnIndex();
|
||||
self::assertEquals('H', $result);
|
||||
}
|
||||
|
||||
public function testGetBadColumnIndex(): void
|
||||
{
|
||||
$this->expectException(PhpSpreadsheetException::class);
|
||||
$this->expectExceptionMessage('Column is outside of current autofilter range.');
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('B');
|
||||
}
|
||||
|
||||
public function testSetColumnIndex(): void
|
||||
{
|
||||
$expectedResult = 'L';
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('H');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
$expectedResult = 'G';
|
||||
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterColumnObject->setColumnIndex($expectedResult);
|
||||
$result = $columnFilter->setColumnIndex($expectedResult);
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
|
||||
$result = $this->testAutoFilterColumnObject->getColumnIndex();
|
||||
$result = $result->getColumnIndex();
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function testGetParent(): void
|
||||
{
|
||||
$result = $this->testAutoFilterColumnObject->getParent();
|
||||
self::assertInstanceOf(AutoFilter::class, $result);
|
||||
}
|
||||
|
||||
public function testSetParent(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('H');
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterColumnObject->setParent($this->mockAutoFilterObject);
|
||||
$result = $columnFilter->setParent(null);
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
}
|
||||
|
||||
public function testGetFilterType(): void
|
||||
public function testVariousSets(): void
|
||||
{
|
||||
$result = $this->testAutoFilterColumnObject->getFilterType();
|
||||
self::assertEquals(Column::AUTOFILTER_FILTERTYPE_FILTER, $result);
|
||||
}
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('H');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
|
||||
public function testSetFilterType(): void
|
||||
{
|
||||
$result = $this->testAutoFilterColumnObject->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
|
||||
$result = $columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
|
||||
$result = $this->testAutoFilterColumnObject->getFilterType();
|
||||
$result = $columnFilter->getFilterType();
|
||||
self::assertEquals(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER, $result);
|
||||
|
||||
$result = $columnFilter->setJoin(Column::AUTOFILTER_COLUMN_JOIN_AND);
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
|
||||
$result = $columnFilter->getJoin();
|
||||
self::assertEquals(Column::AUTOFILTER_COLUMN_JOIN_AND, $result);
|
||||
}
|
||||
|
||||
public function testSetInvalidFilterTypeThrowsException(): void
|
||||
{
|
||||
$this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class);
|
||||
$this->expectException(PhpSpreadsheetException::class);
|
||||
$this->expectExceptionMessage('Invalid filter type for column AutoFilter.');
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('H');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
|
||||
$expectedResult = 'Unfiltered';
|
||||
|
||||
$this->testAutoFilterColumnObject->setFilterType($expectedResult);
|
||||
}
|
||||
|
||||
public function testGetJoin(): void
|
||||
{
|
||||
$result = $this->testAutoFilterColumnObject->getJoin();
|
||||
self::assertEquals(Column::AUTOFILTER_COLUMN_JOIN_OR, $result);
|
||||
}
|
||||
|
||||
public function testSetJoin(): void
|
||||
{
|
||||
$result = $this->testAutoFilterColumnObject->setJoin(Column::AUTOFILTER_COLUMN_JOIN_AND);
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
|
||||
$result = $this->testAutoFilterColumnObject->getJoin();
|
||||
self::assertEquals(Column::AUTOFILTER_COLUMN_JOIN_AND, $result);
|
||||
$columnFilter->setFilterType($expectedResult);
|
||||
}
|
||||
|
||||
public function testSetInvalidJoinThrowsException(): void
|
||||
{
|
||||
$this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class);
|
||||
$this->expectException(PhpSpreadsheetException::class);
|
||||
$this->expectExceptionMessage('Invalid rule connection for column AutoFilter.');
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('H');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
|
||||
$expectedResult = 'Neither';
|
||||
|
||||
$this->testAutoFilterColumnObject->setJoin($expectedResult);
|
||||
}
|
||||
|
||||
public function testSetAttributes(): void
|
||||
{
|
||||
$attributeSet = [
|
||||
'val' => 100,
|
||||
'maxVal' => 200,
|
||||
];
|
||||
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterColumnObject->setAttributes($attributeSet);
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
$columnFilter->setJoin($expectedResult);
|
||||
}
|
||||
|
||||
public function testGetAttributes(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('H');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
$attributeSet = [
|
||||
'val' => 100,
|
||||
'maxVal' => 200,
|
||||
];
|
||||
|
||||
$this->testAutoFilterColumnObject->setAttributes($attributeSet);
|
||||
$result = $columnFilter->setAttributes($attributeSet);
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
|
||||
$result = $this->testAutoFilterColumnObject->getAttributes();
|
||||
self::assertIsArray($result);
|
||||
self::assertCount(count($attributeSet), $result);
|
||||
$result = $columnFilter->getAttributes();
|
||||
self::assertSame($attributeSet, $result);
|
||||
}
|
||||
|
||||
public function testSetAttribute(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('H');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
|
||||
$attributeSet = [
|
||||
'val' => 100,
|
||||
'maxVal' => 200,
|
||||
|
|
@ -151,37 +180,103 @@ class ColumnTest extends TestCase
|
|||
|
||||
foreach ($attributeSet as $attributeName => $attributeValue) {
|
||||
// Setters return the instance to implement the fluent interface
|
||||
$result = $this->testAutoFilterColumnObject->setAttribute($attributeName, $attributeValue);
|
||||
$result = $columnFilter->setAttribute($attributeName, $attributeValue);
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
}
|
||||
self::assertSame($attributeSet, $columnFilter->getAttributes());
|
||||
}
|
||||
|
||||
public function testGetAttribute(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('H');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
|
||||
$attributeSet = [
|
||||
'val' => 100,
|
||||
'maxVal' => 200,
|
||||
];
|
||||
|
||||
$this->testAutoFilterColumnObject->setAttributes($attributeSet);
|
||||
$result = $columnFilter->setAttributes($attributeSet);
|
||||
|
||||
foreach ($attributeSet as $attributeName => $attributeValue) {
|
||||
$result = $this->testAutoFilterColumnObject->getAttribute($attributeName);
|
||||
self::assertEquals($attributeValue, $result);
|
||||
$result = $columnFilter->getAttribute($attributeName);
|
||||
}
|
||||
$result = $this->testAutoFilterColumnObject->getAttribute('nonExistentAttribute');
|
||||
$result = $columnFilter->getAttribute('nonExistentAttribute');
|
||||
self::assertNull($result);
|
||||
}
|
||||
|
||||
public function testClone(): void
|
||||
{
|
||||
$originalRule = $this->testAutoFilterColumnObject->createRule();
|
||||
$result = clone $this->testAutoFilterColumnObject;
|
||||
self::assertInstanceOf(Column::class, $result);
|
||||
self::assertCount(1, $result->getRules());
|
||||
self::assertContainsOnlyInstancesOf(AutoFilter\Column\Rule::class, $result->getRules());
|
||||
$clonedRule = $result->getRules()[0];
|
||||
self::assertNotSame($originalRule, $clonedRule);
|
||||
self::assertSame($result, $clonedRule->getParent());
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('H');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
$originalRule = $columnFilter->getRules();
|
||||
$result = clone $columnFilter;
|
||||
self::assertSame($columnFilter->getColumnIndex(), $result->getColumnIndex());
|
||||
self::assertSame($columnFilter->getFilterType(), $result->getFilterType());
|
||||
self::assertSame($columnFilter->getJoin(), $result->getJoin());
|
||||
self::assertNull($result->getParent());
|
||||
self::assertNotNull($columnFilter->getParent());
|
||||
self::assertContainsOnlyInstancesOf(Rule::class, $result->getRules());
|
||||
$clonedRule = $result->getRules();
|
||||
self::assertCount(1, $clonedRule);
|
||||
self::assertCount(1, $originalRule);
|
||||
self::assertNotSame($originalRule[0], $clonedRule[0]);
|
||||
self::assertSame($originalRule[0]->getRuleType(), $clonedRule[0]->getRuleType());
|
||||
self::assertSame($originalRule[0]->getValue(), $clonedRule[0]->getValue());
|
||||
self::assertSame($originalRule[0]->getOperator(), $clonedRule[0]->getOperator());
|
||||
self::assertSame($originalRule[0]->getGrouping(), $clonedRule[0]->getGrouping());
|
||||
self::assertSame($result, $clonedRule[0]->getParent());
|
||||
}
|
||||
|
||||
public function testRuleManipulation(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('H');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
$originalRules = $columnFilter->getRules();
|
||||
self::assertCount(1, $originalRules);
|
||||
$rule0 = $columnFilter->getRule(0);
|
||||
self::assertSame($originalRules[0], $rule0);
|
||||
$rule1 = $columnFilter->getRule(1);
|
||||
self::assertInstanceOf(Rule::class, $rule1);
|
||||
self::assertNotEquals($originalRules[0], $rule1);
|
||||
self::assertCount(2, $columnFilter->getRules());
|
||||
self::assertSame(Column::AUTOFILTER_COLUMN_JOIN_OR, $columnFilter->getJoin());
|
||||
$columnFilter->setJoin(Column::AUTOFILTER_COLUMN_JOIN_AND);
|
||||
$rule2 = new Rule();
|
||||
$columnFilter->addRule($rule2);
|
||||
self::assertCount(3, $columnFilter->getRules());
|
||||
self::assertSame(Column::AUTOFILTER_COLUMN_JOIN_AND, $columnFilter->getJoin());
|
||||
$columnFilter->deleteRule(2);
|
||||
self::assertCount(2, $columnFilter->getRules());
|
||||
self::assertSame(Column::AUTOFILTER_COLUMN_JOIN_AND, $columnFilter->getJoin());
|
||||
$columnFilter->deleteRule(1);
|
||||
self::assertCount(1, $columnFilter->getRules());
|
||||
self::assertSame(Column::AUTOFILTER_COLUMN_JOIN_OR, $columnFilter->getJoin());
|
||||
$columnFilter->addRule($rule1);
|
||||
$columnFilter->addRule($rule2);
|
||||
$columnFilter->setJoin(Column::AUTOFILTER_COLUMN_JOIN_AND);
|
||||
self::assertCount(3, $columnFilter->getRules());
|
||||
self::assertSame(Column::AUTOFILTER_COLUMN_JOIN_AND, $columnFilter->getJoin());
|
||||
$columnFilter->clearRules();
|
||||
self::assertCount(0, $columnFilter->getRules());
|
||||
self::assertSame(Column::AUTOFILTER_COLUMN_JOIN_OR, $columnFilter->getJoin());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,232 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class DateGroupTest extends SetupTeardown
|
||||
{
|
||||
protected function initSheet(int $year): Worksheet
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getCell('A1')->setValue('Date');
|
||||
$sheet->getCell('B1')->setValue('Time');
|
||||
$sheet->getCell('C1')->setValue('DateTime');
|
||||
$sheet->getCell('C1')->setValue('Row*10');
|
||||
for ($row = 2; $row < 63; ++$row) {
|
||||
$sheet->getCell("A$row")->setValue("=DATE($year,11,30)+$row");
|
||||
$hour = $row % 24;
|
||||
$minute = $row % 10;
|
||||
$second = $row % 20;
|
||||
$sheet->getCell("B$row")->setValue("=TIME($hour,$minute,$second)");
|
||||
$sheet->getCell("C$row")->setValue("=A$row+B$row");
|
||||
$sheet->getCell("D$row")->setValue("=10*$row");
|
||||
}
|
||||
$this->maxRow = $maxRow = 62;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:C$maxRow");
|
||||
|
||||
return $sheet;
|
||||
}
|
||||
|
||||
public function testYearMonthDayGroup(): void
|
||||
{
|
||||
$year = 2011;
|
||||
$sheet = $this->initSheet($year);
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('C');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'year' => $year,
|
||||
'month' => 12,
|
||||
'day' => 6,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([6], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testYearMonthDayHourMinuteSecond1Group(): void
|
||||
{
|
||||
$year = 2011;
|
||||
$sheet = $this->initSheet($year);
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('C');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'year' => $year,
|
||||
'month' => 12,
|
||||
'day' => 6,
|
||||
'hour' => 6,
|
||||
'minute' => 6,
|
||||
'second' => 6,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
$sheet->getCell('C5')->setValue(''); // make an empty cell in range
|
||||
self::assertEquals([6], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testYearMonthDayHourMinuteSecond2Group(): void
|
||||
{
|
||||
$year = 2011;
|
||||
$sheet = $this->initSheet($year);
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('C');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'year' => $year,
|
||||
'month' => 12,
|
||||
'day' => 6,
|
||||
'hour' => 6,
|
||||
'minute' => 6,
|
||||
'second' => 7,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testDayGroupEpoch(): void
|
||||
{
|
||||
$year = 2040;
|
||||
$sheet = $this->initSheet($year);
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('C');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'year' => $year,
|
||||
'month' => 12,
|
||||
'day' => 6,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([6], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testDayGroupNonArray(): void
|
||||
{
|
||||
$year = 2011;
|
||||
$sheet = $this->initSheet($year);
|
||||
$cellA2 = $sheet->getCell('A2')->getCalculatedValue();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('C');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
$cellA2
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testHourGroup(): void
|
||||
{
|
||||
$year = 2011;
|
||||
$sheet = $this->initSheet($year);
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('B');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'hour' => 14,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([14, 38, 62], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testHourMinuteGroup(): void
|
||||
{
|
||||
$year = 2011;
|
||||
$sheet = $this->initSheet($year);
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('B');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'hour' => 14,
|
||||
'minute' => 8,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([38], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testHourMinuteSecondGroup1(): void
|
||||
{
|
||||
$year = 2011;
|
||||
$sheet = $this->initSheet($year);
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('B');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'hour' => 14,
|
||||
'minute' => 8,
|
||||
'second' => 18,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([38], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testHourMinuteSecondGroup2(): void
|
||||
{
|
||||
$year = 2011;
|
||||
$sheet = $this->initSheet($year);
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('B');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'hour' => 14,
|
||||
'minute' => 8,
|
||||
'second' => 19,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([], $this->getVisible());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class RuleCustomTest extends SetupTeardown
|
||||
{
|
||||
protected function initSheet(): Worksheet
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getCell('A1')->setValue('Heading');
|
||||
$sheet->getCell('A2')->setValue(2);
|
||||
$sheet->getCell('A3')->setValue(3);
|
||||
$sheet->getCell('A4')->setValue(4);
|
||||
$sheet->getCell('B1')->setValue('Heading2');
|
||||
$sheet->getCell('B2')->setValue(1);
|
||||
$sheet->getCell('B3')->setValue(2);
|
||||
$sheet->getCell('B4')->setValue(3);
|
||||
$this->maxRow = $maxRow = 4;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:B$maxRow");
|
||||
|
||||
return $sheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCondition
|
||||
*/
|
||||
public function testRuleCondition(array $expectedResult, string $condition): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
$condition,
|
||||
3
|
||||
)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals($expectedResult, $this->getVisible());
|
||||
}
|
||||
|
||||
public function providerCondition(): array
|
||||
{
|
||||
return [
|
||||
[[3], Rule::AUTOFILTER_COLUMN_RULE_EQUAL],
|
||||
[[2, 4], Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL],
|
||||
[[4], Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN],
|
||||
[[3, 4], Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL],
|
||||
[[2], Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN],
|
||||
[[2, 3], Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception as SpException;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class RuleDateGroupTest extends SetupTeardown
|
||||
{
|
||||
protected function initSheet(): Worksheet
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getCell('A1')->setValue('Date');
|
||||
$sheet->getCell('A2')->setValue('=DATE(2011,1,10)');
|
||||
$sheet->getCell('A3')->setValue('=DATE(2012,1,10)');
|
||||
$sheet->getCell('A4')->setValue('=DATE(2011,1,10)');
|
||||
$sheet->getCell('A5')->setValue('=DATE(2012,2,10)');
|
||||
$sheet->getCell('A6')->setValue('=DATE(2012,1,1)');
|
||||
$sheet->getCell('A7')->setValue('=DATE(2012,12,31)');
|
||||
$sheet->getCell('B1')->setValue('Heading2');
|
||||
$sheet->getCell('B2')->setValue(1);
|
||||
$sheet->getCell('B3')->setValue(2);
|
||||
$sheet->getCell('B4')->setValue(3);
|
||||
$sheet->getCell('B5')->setValue(4);
|
||||
$sheet->getCell('B6')->setValue(5);
|
||||
$sheet->getCell('B7')->setValue(6);
|
||||
$this->maxRow = $maxRow = 7;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:B$maxRow");
|
||||
|
||||
return $sheet;
|
||||
}
|
||||
|
||||
public function testYearGroup(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'year' => 2012,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([3, 5, 6, 7], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testYearGroupWithInvalidIndex(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'year' => 2012,
|
||||
'xyz' => 5,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([3, 5, 6, 7], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testYearGroupNoValidIndexes(): void
|
||||
{
|
||||
$this->expectException(SpException::class);
|
||||
$this->expectExceptionMessage('Invalid rule value for column AutoFilter Rule.');
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'zzyear' => 2012,
|
||||
'xyz' => 5,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([3, 5, 6, 7], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testYearGroupBadRuleType(): void
|
||||
{
|
||||
$this->expectException(SpException::class);
|
||||
$this->expectExceptionMessage('Invalid rule type for column AutoFilter Rule.');
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'year' => 2012,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
'xyz'
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([3, 5, 6, 7], $this->getVisible());
|
||||
}
|
||||
|
||||
public function testYearMonthGroup(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
[
|
||||
'year' => 2012,
|
||||
'month' => 1,
|
||||
]
|
||||
)
|
||||
->setRuleType(
|
||||
Rule::AUTOFILTER_RULETYPE_DATEGROUP
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals([3, 6], $this->getVisible());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception as SpException;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class RuleTest extends SetupTeardown
|
||||
{
|
||||
protected function initSheet(): Worksheet
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getCell('A1')->setValue('Heading');
|
||||
$sheet->getCell('A2')->setValue(2);
|
||||
$sheet->getCell('A3')->setValue(3);
|
||||
$sheet->getCell('A4')->setValue(4);
|
||||
$sheet->getCell('B1')->setValue('Heading2');
|
||||
$sheet->getCell('B2')->setValue(1);
|
||||
$sheet->getCell('B3')->setValue(2);
|
||||
$sheet->getCell('B4')->setValue(3);
|
||||
$this->maxRow = $maxRow = 4;
|
||||
$autoFilter = $sheet->getAutoFilter();
|
||||
$autoFilter->setRange("A1:B$maxRow");
|
||||
|
||||
return $sheet;
|
||||
}
|
||||
|
||||
public function testRule(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
self::assertEquals(Rule::AUTOFILTER_RULETYPE_FILTER, $autoFilterRuleObject->getRuleType());
|
||||
self::assertEquals([3], $this->getVisible());
|
||||
$ruleParent = $autoFilterRuleObject->getParent();
|
||||
if ($ruleParent === null) {
|
||||
self::fail('Unexpected null parent');
|
||||
} else {
|
||||
self::assertEquals('A', $ruleParent->getColumnIndex());
|
||||
self::assertSame($columnFilter, $ruleParent);
|
||||
}
|
||||
}
|
||||
|
||||
public function testSetParent(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$autoFilterRuleObject = new Rule();
|
||||
$autoFilterRuleObject->setParent($sheet->getAutoFilter()->getColumn('B'));
|
||||
$columnFilter = $autoFilterRuleObject->getParent();
|
||||
if ($columnFilter === null) {
|
||||
self::fail('Unexpected null parent');
|
||||
} else {
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
self::assertEquals(Rule::AUTOFILTER_RULETYPE_FILTER, $autoFilterRuleObject->getRuleType());
|
||||
self::assertEquals([4], $this->getVisible());
|
||||
}
|
||||
}
|
||||
|
||||
public function testBadSetRule(): void
|
||||
{
|
||||
$this->expectException(SpException::class);
|
||||
$this->expectExceptionMessage('Invalid operator for column AutoFilter Rule.');
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
'xyz',
|
||||
3
|
||||
);
|
||||
}
|
||||
|
||||
public function testBadSetGrouping(): void
|
||||
{
|
||||
$this->expectException(SpException::class);
|
||||
$this->expectExceptionMessage('Invalid grouping for column AutoFilter Rule.');
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
'',
|
||||
3
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
$autoFilterRuleObject->setGrouping('xyz');
|
||||
}
|
||||
|
||||
public function testClone(): void
|
||||
{
|
||||
$sheet = $this->initSheet();
|
||||
$columnFilter = $sheet->getAutoFilter()->getColumn('A');
|
||||
$columnFilter->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER);
|
||||
$columnFilter->createRule()
|
||||
->setRule(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
3
|
||||
);
|
||||
$autoFilterRuleObject = new Rule($columnFilter);
|
||||
$result = clone $autoFilterRuleObject;
|
||||
self::assertSame($autoFilterRuleObject->getRuleType(), $result->getRuleType());
|
||||
self::assertSame($autoFilterRuleObject->getValue(), $result->getValue());
|
||||
self::assertSame($autoFilterRuleObject->getRuleType(), $result->getRuleType());
|
||||
self::assertSame($autoFilterRuleObject->getOperator(), $result->getOperator());
|
||||
self::assertSame($autoFilterRuleObject->getGrouping(), $result->getGrouping());
|
||||
self::assertNotNull($autoFilterRuleObject->getParent());
|
||||
self::assertNull($result->getParent());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\AutoFilter;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class SetupTeardown extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var ?Spreadsheet
|
||||
*/
|
||||
private $spreadsheet;
|
||||
|
||||
/**
|
||||
* @var ?Worksheet
|
||||
*/
|
||||
private $sheet;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $maxRow = 4;
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$this->sheet = null;
|
||||
if ($this->spreadsheet !== null) {
|
||||
$this->spreadsheet->disconnectWorksheets();
|
||||
$this->spreadsheet = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getSpreadsheet(): Spreadsheet
|
||||
{
|
||||
if ($this->spreadsheet !== null) {
|
||||
return $this->spreadsheet;
|
||||
}
|
||||
$this->spreadsheet = new Spreadsheet();
|
||||
|
||||
return $this->spreadsheet;
|
||||
}
|
||||
|
||||
protected function getSheet(): Worksheet
|
||||
{
|
||||
if ($this->sheet !== null) {
|
||||
return $this->sheet;
|
||||
}
|
||||
$this->sheet = $this->getSpreadsheet()->getActiveSheet();
|
||||
|
||||
return $this->sheet;
|
||||
}
|
||||
|
||||
public function getVisible(): array
|
||||
{
|
||||
$sheet = $this->getSheet();
|
||||
$sheet->getAutoFilter()->showHideRows();
|
||||
$actualVisible = [];
|
||||
for ($row = 2; $row <= $this->maxRow; ++$row) {
|
||||
if ($sheet->getRowDimension($row)->getVisible()) {
|
||||
$actualVisible[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
return $actualVisible;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue