Fixed broken build after recent autofilter changes

This commit is contained in:
Mark Baker 2012-08-15 13:20:34 +01:00
parent 55aa7b8d2b
commit 83afa87bf3
10 changed files with 282 additions and 18 deletions

View File

@ -1193,7 +1193,6 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader
} }
} }
} }
var_dump($autoFilter);
} }
if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) { if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) {

View File

@ -239,6 +239,264 @@ class PHPExcel_Worksheet_AutoFilter
return $this; return $this;
} }
private static function _filterTestInSimpleDataSet($cellValue,$dataSet)
{
$dataSetValues = $dataSet['filterValues'];
$blanks = $dataSet['blanks'];
if (($cellValue == '') || ($cellValue === NULL)) {
return $blanks;
}
return in_array($cellValue,$dataSetValues);
}
private static function _filterTestInDateGroupSet($cellValue,$dataSet)
{
$dateSet = $dataSet['filterValues'];
$blanks = $dataSet['blanks'];
if (($cellValue == '') || ($cellValue === NULL)) {
return $blanks;
}
if (is_numeric($cellValue)) {
$dateValue = PHPExcel_Shared_Date::ExcelToPHP($cellValue);
if ($cellValue < 1) {
// Just the time part
$dtVal = date('His',$dateValue);
$dateSet = $dateSet['time'];
} elseif($cellValue == floor($cellValue)) {
// Just the date part
$dtVal = date('Ymd',$dateValue);
$dateSet = $dateSet['date'];
} else {
// date and time parts
$dtVal = date('YmdHis',$dateValue);
$dateSet = $dateSet['dateTime'];
}
foreach($dateSet as $dateValue) {
// Use of substr to extract value at the appropriate group level
if (substr($dtVal,0,strlen($dateValue)) == $dateValue)
return TRUE;
}
}
return FALSE;
}
private static function _filterTypeCustomFilters($cellValue,$ruleSet)
{
$dataSet = $ruleSet['filterRules'];
$join = $ruleSet['join'];
$returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_ANDOR_AND);
foreach($dataSet as $rule) {
if (is_numeric($rule['value'])) {
// Numeric values are tested using the appropriate operator
switch ($rule['operator']) {
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL :
$retVal = ($cellValue == $rule['value']);
break;
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL :
$retVal = ($cellValue != $rule['value']);
break;
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN :
$retVal = ($cellValue > $rule['value']);
break;
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL :
$retVal = ($cellValue >= $rule['value']);
break;
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN :
$retVal = ($cellValue < $rule['value']);
break;
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL :
$retVal = ($cellValue <= $rule['value']);
break;
}
} else {
// String values are always tested for equality
$retVal = preg_match('/^'.$rule['value'].'$/',$cellValue);
}
// If there are multiple conditions, then we need to test both using the appropriate join operator
switch ($join) {
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_ANDOR_OR :
$returnVal = $returnVal || $retVal;
// Break as soon as we have a match for OR joins
if ($returnVal)
return $returnVal;
break;
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_ANDOR_AND :
$returnVal = $returnVal && $retVal;
break;
}
}
return $returnVal;
}
private static function _filterTypeDynamicFilters($cellValue,$testSet)
{
return TRUE;
}
private static function _filterTypeTopTenFilters($cellValue,$testSet)
{
return TRUE;
}
private static $_fromReplace = array('\*', '\?', '~~', '~.*', '~.?');
private static $_toReplace = array('.*', '.', '~', '\*', '\?');
/**
* Apply the AutoFilter rules to the AutoFilter Range
*
* @throws PHPExcel_Exception
* @return PHPExcel_Worksheet_AutoFilter
*/
public function showHideRows()
{
list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range);
// The heading row should always be visible
echo 'AutoFilter Heading Row ',$rangeStart[1],' is always SHOWN',PHP_EOL;
$this->_workSheet->getRowDimension($rangeStart[1])->setVisible(TRUE);
$columnFilterTests = array();
foreach($this->_columns as $columnID => $filterColumn) {
$rules = $filterColumn->getRules();
switch ($filterColumn->getFilterType()) {
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER :
$ruleValues = array();
// Build a list of the filter value selections
foreach($rules as $rule) {
$ruleType = $rule->getRuleType();
$ruleValues[] = $rule->getValue();
}
// Test if we want to include blanks in our filter criteria
$blanks = FALSE;
$ruleDataSet = array_filter($ruleValues);
if (count($ruleValues) != count($ruleDataSet))
$blanks = TRUE;
if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER) {
// Filter on absolute values
$columnFilterTests[$columnID] = array(
'method' => '_filterTestInSimpleDataSet',
'arguments' => array( 'filterValues' => $ruleDataSet,
'blanks' => $blanks
)
);
} else {
// Filter on date group values
$arguments = array();
foreach($ruleDataSet as $ruleValue) {
$date = $time = '';
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) &&
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== ''))
$date .= sprintf('%04d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]);
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) &&
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != ''))
$date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]);
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) &&
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== ''))
$date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]);
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) &&
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== ''))
$time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]);
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) &&
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== ''))
$time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]);
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) &&
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== ''))
$time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]);
$dateTime = $date . $time;
$arguments['date'][] = $date;
$arguments['time'][] = $time;
$arguments['dateTime'][] = $dateTime;
}
// Remove empty elements
$arguments['date'] = array_filter($arguments['date']);
$arguments['time'] = array_filter($arguments['time']);
$arguments['dateTime'] = array_filter($arguments['dateTime']);
$columnFilterTests[$columnID] = array(
'method' => '_filterTestInDateGroupSet',
'arguments' => array( 'filterValues' => $arguments,
'blanks' => $blanks
)
);
}
break;
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER :
$ruleValues = array();
// Build a list of the filter value selections
foreach($rules as $rule) {
$ruleType = $rule->getRuleType();
$ruleValue = $rule->getValue();
if (!is_numeric($ruleValue)) {
// Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards
var_dump($ruleValue);
echo ' = > ';
$ruleValue = preg_quote($ruleValue);
var_dump($ruleValue);
echo ' = > ';
$ruleValue = str_replace(self::$_fromReplace,self::$_toReplace,$ruleValue);
var_dump($ruleValue);
}
$ruleValues[] = array( 'operator' => $rule->getOperator(),
'value' => $ruleValue
);
}
$join = $filterColumn->getAndOr();
$columnFilterTests[$columnID] = array(
'method' => '_filterTypeCustomFilters',
'arguments' => array( 'filterRules' => $ruleValues,
'join' => $join
)
);
break;
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER :
$columnFilterTests[$columnID] = array(
'method' => '_filterTypeDynamicFilters',
'arguments' => $ruleValues
);
break;
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER :
$columnFilterTests[$columnID] = array(
'method' => '_filterTypeTopTenFilters',
'arguments' => $ruleValues
);
break;
}
}
echo 'Column Filter Test CRITERIA',PHP_EOL;
var_dump($columnFilterTests);
for ($row = $rangeStart[1]+1; $row <= $rangeEnd[1]; ++$row) {
echo 'Testing Row = ',$row,PHP_EOL;
$result = TRUE;
foreach($columnFilterTests as $columnID => $columnFilterTest) {
echo 'Testing cell ',$columnID.$row,PHP_EOL;
$cellValue = $this->_workSheet->getCell($columnID.$row)->getCalculatedValue();
echo 'Value is ',$cellValue,PHP_EOL;
// Execute the filter test
$result = $result &&
call_user_func_array(
array('PHPExcel_Worksheet_AutoFilter',$columnFilterTest['method']),
array(
$cellValue,
$columnFilterTest['arguments']
)
);
echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL;
// If filter test has resulted in FALSE, exit straightaway rather than running any more tests
if (!$result)
break;
}
echo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL;
$this->_workSheet->getRowDimension($row)->setVisible($result);
}
return $this;
}
/** /**
* Implement PHP __clone to create a deep clone, not just a shallow copy. * Implement PHP __clone to create a deep clone, not just a shallow copy.
*/ */

View File

@ -49,7 +49,6 @@ class PHPExcel_Worksheet_AutoFilter_Column
// colorFilter // colorFilter
// extLst // extLst
// iconFilter // iconFilter
// topTen
self::AUTOFILTER_FILTERTYPE_FILTER, self::AUTOFILTER_FILTERTYPE_FILTER,
self::AUTOFILTER_FILTERTYPE_CUSTOMFILTER, self::AUTOFILTER_FILTERTYPE_CUSTOMFILTER,
self::AUTOFILTER_FILTERTYPE_DYNAMICFILTER, self::AUTOFILTER_FILTERTYPE_DYNAMICFILTER,
@ -60,7 +59,7 @@ class PHPExcel_Worksheet_AutoFilter_Column
const AUTOFILTER_COLUMN_ANDOR_AND = 'and'; const AUTOFILTER_COLUMN_ANDOR_AND = 'and';
const AUTOFILTER_COLUMN_ANDOR_OR = 'or'; const AUTOFILTER_COLUMN_ANDOR_OR = 'or';
private static $_ruleConnections = array( private static $_ruleJoin = array(
self::AUTOFILTER_COLUMN_ANDOR_AND, self::AUTOFILTER_COLUMN_ANDOR_AND,
self::AUTOFILTER_COLUMN_ANDOR_OR, self::AUTOFILTER_COLUMN_ANDOR_OR,
); );
@ -208,7 +207,7 @@ class PHPExcel_Worksheet_AutoFilter_Column
public function setAndOr($pAndOr = self::AUTOFILTER_COLUMN_ANDOR_OR) { public function setAndOr($pAndOr = self::AUTOFILTER_COLUMN_ANDOR_OR) {
// Lowercase And/Or // Lowercase And/Or
$pAndOr = strtolower($pAndOr); $pAndOr = strtolower($pAndOr);
if (!in_array($pAndOr,self::$_ruleConnections)) { if (!in_array($pAndOr,self::$_ruleJoin)) {
throw new PHPExcel_Exception('Invalid rule connection for column AutoFilter.'); throw new PHPExcel_Exception('Invalid rule connection for column AutoFilter.');
} }

View File

@ -347,14 +347,15 @@ class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_Write
private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0)
{ {
// definedName for autoFilter // definedName for autoFilter
if ($pSheet->getAutoFilter()->getRange() !== '') { $autoFilterRange = $pSheet->getAutoFilter()->getRange();
if (!empty($autoFilterRange)) {
$objWriter->startElement('definedName'); $objWriter->startElement('definedName');
$objWriter->writeAttribute('name', '_xlnm._FilterDatabase'); $objWriter->writeAttribute('name', '_xlnm._FilterDatabase');
$objWriter->writeAttribute('localSheetId', $pSheetId); $objWriter->writeAttribute('localSheetId', $pSheetId);
$objWriter->writeAttribute('hidden', '1'); $objWriter->writeAttribute('hidden', '1');
// Create absolute coordinate and write as raw text // Create absolute coordinate and write as raw text
$range = PHPExcel_Cell::splitRange($pSheet->getAutoFilter()->getRange()); $range = PHPExcel_Cell::splitRange($autoFilterRange);
$range = $range[0]; $range = $range[0];
// Strip any worksheet ref so we can make the cell ref absolute // Strip any worksheet ref so we can make the cell ref absolute
if (strpos($range[0],'!') !== false) { if (strpos($range[0],'!') !== false) {

View File

@ -148,9 +148,10 @@ class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_Writ
// sheetPr // sheetPr
$objWriter->startElement('sheetPr'); $objWriter->startElement('sheetPr');
//$objWriter->writeAttribute('codeName', $pSheet->getTitle()); //$objWriter->writeAttribute('codeName', $pSheet->getTitle());
$autoFilterRange = $pSheet->getAutoFilter()->getRange();
if ($pSheet->getAutoFilter()->getRange() !== '') { if (!empty($autoFilterRange)) {
$objWriter->writeAttribute('filterMode', 1); $objWriter->writeAttribute('filterMode', 1);
// $pSheet->getAutoFilter()->showHideRows();
} }
// tabColor // tabColor
@ -734,12 +735,13 @@ class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_Writ
*/ */
private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
{ {
if ($pSheet->getAutoFilter()->getRange() !== '') { $autoFilterRange = $pSheet->getAutoFilter()->getRange();
if (!empty($autoFilterRange)) {
// autoFilter // autoFilter
$objWriter->startElement('autoFilter'); $objWriter->startElement('autoFilter');
// Strip any worksheet reference from the filter coordinates // Strip any worksheet reference from the filter coordinates
$range = PHPExcel_Cell::splitRange($pSheet->getAutoFilter()->getRange()); $range = PHPExcel_Cell::splitRange($autoFilterRange);
$range = $range[0]; $range = $range[0];
// Strip any worksheet ref // Strip any worksheet ref
if (strpos($range[0],'!') !== false) { if (strpos($range[0],'!') !== false) {

View File

@ -274,6 +274,8 @@ class PHPExcel_Writer_Excel5 implements PHPExcel_Writer_IWriter
{ {
// 1-based index to BstoreContainer // 1-based index to BstoreContainer
$blipIndex = 0; $blipIndex = 0;
$lastReducedSpId = 0;
$lastSpId = 0;
foreach ($this->_phpExcel->getAllsheets() as $sheet) { foreach ($this->_phpExcel->getAllsheets() as $sheet) {
// sheet index // sheet index
@ -282,7 +284,8 @@ class PHPExcel_Writer_Excel5 implements PHPExcel_Writer_IWriter
$escher = null; $escher = null;
// check if there are any shapes for this sheet // check if there are any shapes for this sheet
if (count($sheet->getDrawingCollection()) == 0 && $sheet->getAutoFilter()->getRange() === '') { $filterRange = $sheet->getAutoFilter()->getRange();
if (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) {
continue; continue;
} }
@ -360,8 +363,8 @@ class PHPExcel_Writer_Excel5 implements PHPExcel_Writer_IWriter
} }
// AutoFilters // AutoFilters
if($sheet->getAutoFilter()->getRange() !== ''){ if(!empty($filterRange)){
$rangeBounds = PHPExcel_Cell::rangeBoundaries($sheet->getAutoFilter()->getRange()); $rangeBounds = PHPExcel_Cell::rangeBoundaries($filterRange);
$iNumColStart = $rangeBounds[0][0]; $iNumColStart = $rangeBounds[0][0];
$iNumColEnd = $rangeBounds[1][0]; $iNumColEnd = $rangeBounds[1][0];

View File

@ -783,8 +783,9 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter
// write autofilters, if any // write autofilters, if any
for ($i = 0; $i < $total_worksheets; ++$i) { for ($i = 0; $i < $total_worksheets; ++$i) {
$sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter(); $sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter();
if($sheetAutoFilter->getRange() !== ''){ $autoFilterRange = $sheetAutoFilter->getRange();
$rangeBounds = PHPExcel_Cell::rangeBoundaries($sheetAutoFilter->getRange()); if(!empty($autoFilterRange)) {
$rangeBounds = PHPExcel_Cell::rangeBoundaries($autoFilterRange);
//Autofilter built in name //Autofilter built in name
$name = pack('C', 0x0D); $name = pack('C', 0x0D);

View File

@ -390,8 +390,8 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
$this->_writeColinfo($this->_colinfo[$i]); $this->_writeColinfo($this->_colinfo[$i]);
} }
} }
$autoFilterRange = $_phpSheet->getAutoFilter()->getRange();
if ($_phpSheet->getAutoFilter()->getRange() !== '') { if (!empty($autoFilterRange)) {
// Write AUTOFILTERINFO // Write AUTOFILTERINFO
$this->_writeAutoFilterInfo(); $this->_writeAutoFilterInfo();
} }

View File

@ -782,7 +782,8 @@ class PHPExcel_Writer_HTML implements PHPExcel_Writer_IWriter {
$css['vertical-align'] = $this->_mapVAlign($pStyle->getVertical()); $css['vertical-align'] = $this->_mapVAlign($pStyle->getVertical());
if ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) { if ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) {
$css['text-align'] = $textAlign; $css['text-align'] = $textAlign;
if(in_array($textAlign,array('left','right'))) $css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px'; if(in_array($textAlign,array('left','right')))
$css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px';
} }
// Return // Return