Merge pull request #270 from PowerKiKi/issue_31
Binary comparaison of strings are case insensitive
This commit is contained in:
commit
56c9d079d1
|
@ -3557,15 +3557,37 @@ class PHPExcel_Calculation {
|
|||
if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); }
|
||||
if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); }
|
||||
|
||||
// Use case insensitive comparaison if not OpenOffice mode
|
||||
if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE)
|
||||
{
|
||||
if (is_string($operand1)) {
|
||||
$operand1 = strtoupper($operand1);
|
||||
}
|
||||
|
||||
if (is_string($operand2)) {
|
||||
$operand2 = strtoupper($operand2);
|
||||
}
|
||||
}
|
||||
|
||||
$useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE;
|
||||
|
||||
// execute the necessary operation
|
||||
switch ($operation) {
|
||||
// Greater than
|
||||
case '>':
|
||||
$result = ($operand1 > $operand2);
|
||||
if ($useLowercaseFirstComparison) {
|
||||
$result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0;
|
||||
} else {
|
||||
$result = ($operand1 > $operand2);
|
||||
}
|
||||
break;
|
||||
// Less than
|
||||
case '<':
|
||||
$result = ($operand1 < $operand2);
|
||||
if ($useLowercaseFirstComparison) {
|
||||
$result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0;
|
||||
} else {
|
||||
$result = ($operand1 < $operand2);
|
||||
}
|
||||
break;
|
||||
// Equality
|
||||
case '=':
|
||||
|
@ -3573,11 +3595,19 @@ class PHPExcel_Calculation {
|
|||
break;
|
||||
// Greater than or equal
|
||||
case '>=':
|
||||
$result = ($operand1 >= $operand2);
|
||||
if ($useLowercaseFirstComparison) {
|
||||
$result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0;
|
||||
} else {
|
||||
$result = ($operand1 >= $operand2);
|
||||
}
|
||||
break;
|
||||
// Less than or equal
|
||||
case '<=':
|
||||
$result = ($operand1 <= $operand2);
|
||||
if ($useLowercaseFirstComparison) {
|
||||
$result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0;
|
||||
} else {
|
||||
$result = ($operand1 <= $operand2);
|
||||
}
|
||||
break;
|
||||
// Inequality
|
||||
case '<>':
|
||||
|
@ -3592,6 +3622,21 @@ class PHPExcel_Calculation {
|
|||
return TRUE;
|
||||
} // function _executeBinaryComparisonOperation()
|
||||
|
||||
/**
|
||||
* Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters
|
||||
* @param string $str1
|
||||
* @param string $str2
|
||||
* @return integer
|
||||
*/
|
||||
private function strcmpLowercaseFirst($str1, $str2)
|
||||
{
|
||||
$from = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||
$to = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
$inversedStr1 = strtr($str1, $from, $to);
|
||||
$inversedStr2 = strtr($str2, $from, $to);
|
||||
|
||||
return strcmp($inversedStr1, $inversedStr2);
|
||||
}
|
||||
|
||||
private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) {
|
||||
// Validate the two operands
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
require_once 'testDataFileIterator.php';
|
||||
|
||||
class CalculationTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
if (!defined('PHPEXCEL_ROOT')) {
|
||||
define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');
|
||||
}
|
||||
require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerBinaryComparisonOperation
|
||||
*/
|
||||
public function testBinaryComparisonOperation($formula, $expectedResultExcel, $expectedResultOpenOffice)
|
||||
{
|
||||
PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL);
|
||||
$resultExcel = \PHPExcel_Calculation::getInstance()->_calculateFormulaValue($formula);
|
||||
$this->assertEquals($expectedResultExcel, $resultExcel, 'should be Excel compatible');
|
||||
|
||||
PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE);
|
||||
$resultOpenOffice = \PHPExcel_Calculation::getInstance()->_calculateFormulaValue($formula);
|
||||
$this->assertEquals($expectedResultOpenOffice, $resultOpenOffice, 'should be OpenOffice compatible');
|
||||
}
|
||||
|
||||
public function providerBinaryComparisonOperation()
|
||||
{
|
||||
return new testDataFileIterator('rawTestData/CalculationBinaryComparisonOperation.data');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
# formula, expectedResultExcel, expectedResultOpenOffice
|
||||
'=TRUE', TRUE, TRUE
|
||||
'=1 + 2.5', 3.5, 3.5
|
||||
'=2.5 + 1', 3.5, 3.5
|
||||
'=1 - 2.5', -1.5, -1.5
|
||||
'=2.5 - 1', 1.5, 1.5
|
||||
'=3 > 1', TRUE, TRUE
|
||||
'=3 > 3', FALSE, FALSE
|
||||
'=1 > 3', FALSE, FALSE
|
||||
'=3 < 1', FALSE, FALSE
|
||||
'=3 < 3', FALSE, FALSE
|
||||
'=1 < 3', TRUE, TRUE
|
||||
'=3 = 1', FALSE, FALSE
|
||||
'=3 = 3', TRUE, TRUE
|
||||
'=1 = 1.0', TRUE, TRUE
|
||||
'=3 >= 1', TRUE, TRUE
|
||||
'=3 >= 3', TRUE, TRUE
|
||||
'=1 >= 3', FALSE, FALSE
|
||||
'=3 <= 1', FALSE, FALSE
|
||||
'=3 <= 3', TRUE, TRUE
|
||||
'=1 <= 3', TRUE, TRUE
|
||||
'=3 <> 1', TRUE, TRUE
|
||||
'=3 <> 3', FALSE, FALSE
|
||||
'=1 <> 1.0', FALSE, FALSE
|
||||
'="a" > "a"', FALSE, FALSE
|
||||
'="A" > "A"', FALSE, FALSE
|
||||
'="A" > "a"', FALSE, TRUE
|
||||
'="a" > "A"', FALSE, FALSE
|
||||
'="a" < "a"', FALSE, FALSE
|
||||
'="A" < "A"', FALSE, FALSE
|
||||
'="A" < "a"', FALSE, FALSE
|
||||
'="a" < "A"', FALSE, TRUE
|
||||
'="a" = "a"', TRUE, TRUE
|
||||
'="A" = "A"', TRUE, TRUE
|
||||
'="A" = "a"', TRUE, FALSE
|
||||
'="a" = "A"', TRUE, FALSE
|
||||
'="a" <= "a"', TRUE, TRUE
|
||||
'="A" <= "A"', TRUE, TRUE
|
||||
'="A" <= "a"', TRUE, FALSE
|
||||
'="a" <= "A"', TRUE, TRUE
|
||||
'="a" >= "a"', TRUE, TRUE
|
||||
'="A" >= "A"', TRUE, TRUE
|
||||
'="A" >= "a"', TRUE, TRUE
|
||||
'="a" >= "A"', TRUE, FALSE
|
||||
'="a" <> "a"', FALSE, FALSE
|
||||
'="A" <> "A"', FALSE, FALSE
|
||||
'="A" <> "a"', FALSE, TRUE
|
||||
'="a" <> "A"', FALSE, TRUE
|
||||
'="A" > "b"', FALSE, TRUE
|
||||
'="a" > "b"', FALSE, FALSE
|
||||
'="b" > "a"', TRUE, TRUE
|
||||
'="b" > "A"', TRUE, FALSE
|
||||
'="a2" > "a10"', TRUE, TRUE // Test natural sorting is not used
|
Loading…
Reference in New Issue