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($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); }
|
||||||
if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); }
|
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
|
// execute the necessary operation
|
||||||
switch ($operation) {
|
switch ($operation) {
|
||||||
// Greater than
|
// Greater than
|
||||||
case '>':
|
case '>':
|
||||||
$result = ($operand1 > $operand2);
|
if ($useLowercaseFirstComparison) {
|
||||||
|
$result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0;
|
||||||
|
} else {
|
||||||
|
$result = ($operand1 > $operand2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
// Less than
|
// Less than
|
||||||
case '<':
|
case '<':
|
||||||
$result = ($operand1 < $operand2);
|
if ($useLowercaseFirstComparison) {
|
||||||
|
$result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0;
|
||||||
|
} else {
|
||||||
|
$result = ($operand1 < $operand2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
// Equality
|
// Equality
|
||||||
case '=':
|
case '=':
|
||||||
|
@ -3573,11 +3595,19 @@ class PHPExcel_Calculation {
|
||||||
break;
|
break;
|
||||||
// Greater than or equal
|
// Greater than or equal
|
||||||
case '>=':
|
case '>=':
|
||||||
$result = ($operand1 >= $operand2);
|
if ($useLowercaseFirstComparison) {
|
||||||
|
$result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0;
|
||||||
|
} else {
|
||||||
|
$result = ($operand1 >= $operand2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
// Less than or equal
|
// Less than or equal
|
||||||
case '<=':
|
case '<=':
|
||||||
$result = ($operand1 <= $operand2);
|
if ($useLowercaseFirstComparison) {
|
||||||
|
$result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0;
|
||||||
|
} else {
|
||||||
|
$result = ($operand1 <= $operand2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
// Inequality
|
// Inequality
|
||||||
case '<>':
|
case '<>':
|
||||||
|
@ -3592,6 +3622,21 @@ class PHPExcel_Calculation {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} // function _executeBinaryComparisonOperation()
|
} // 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) {
|
private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) {
|
||||||
// Validate the two operands
|
// 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