From 2b93379453c3c5ac7ecc9b49008f0b670d57c07e Mon Sep 17 00:00:00 2001 From: Henrik Elsner Date: Sat, 16 Jan 2021 20:11:37 +0100 Subject: [PATCH 1/9] [TASK]: Adapt constraints to v11 compatibility --- Tests/Functional/FunctionalTestCase.php | 64 - Tests/Functional/Parser/QueryParserTest.php | 1292 ------------------- composer.json | 10 +- ext_emconf.php | 4 +- 4 files changed, 7 insertions(+), 1363 deletions(-) delete mode 100644 Tests/Functional/FunctionalTestCase.php delete mode 100644 Tests/Functional/Parser/QueryParserTest.php diff --git a/Tests/Functional/FunctionalTestCase.php b/Tests/Functional/FunctionalTestCase.php deleted file mode 100644 index 76573c8..0000000 --- a/Tests/Functional/FunctionalTestCase.php +++ /dev/null @@ -1,64 +0,0 @@ -scenarioDataSetDirectory . $scenarioName . '.csv'; - $scenarioFileName = GeneralUtility::getFileAbsFileName($scenarioFileName); - $this->importCSVDataSet($scenarioFileName); - } - - /** - * @param string $scenarioName - */ - protected function importAssertCSVScenario(string $scenarioName = ''): void - { - $scenarioFileName = $this->assertionDataSetDirectory . $scenarioName . '.csv'; - $scenarioFileName = GeneralUtility::getFileAbsFileName($scenarioFileName); - $this->assertCSVDataSet($scenarioFileName); - } -} diff --git a/Tests/Functional/Parser/QueryParserTest.php b/Tests/Functional/Parser/QueryParserTest.php deleted file mode 100644 index adc2f54..0000000 --- a/Tests/Functional/Parser/QueryParserTest.php +++ /dev/null @@ -1,1292 +0,0 @@ -originalTimeZone = date_default_timezone_get(); - date_default_timezone_set('Europe/Berlin'); - $this->subject = new QueryParser(); - } - - /** - * - */ - protected function tearDown(): void - { - date_default_timezone_set($this->originalTimeZone); - parent::tearDown(); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleEqualQueryDataProvider() : array - { - return [ - 'integer value as type string' => [42, 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => 42]], - 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => 42]], - 'float value as type string' => [42.5, 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => 42.5]], - 'string float value as type string' => ['42.5', 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => 42.5]], - 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => '42,5']], - 'string as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => 'foo']], - - 'integer value as type integer' => [42, 'integer', 'SELECT WHERE `title` = 42', []], - 'string as number value as type integer' => ['42', 'integer', 'SELECT WHERE `title` = 42', []], - 'integer(negative) value as type integer' => [-5, 'integer', 'SELECT WHERE `title` = -5', []], - 'string(negative) as number value as type integer' => ['-5', 'integer', 'SELECT WHERE `title` = -5', []], - - 'integer(1) value as type boolean' => [[1], 'boolean', 'SELECT WHERE `title` = :dcValue3', ['dcValue1' => 1, 'dcValue2' => null, 'dcValue3' => 1]], - 'string(1) as number value as type boolean' => [['1'], 'boolean', 'SELECT WHERE `title` = :dcValue3', ['dcValue1' => '1', 'dcValue2' => null, 'dcValue3' => '1']], - 'integer(0) value as type boolean' => [[0], 'boolean', 'SELECT WHERE `title` = :dcValue3', ['dcValue1' => 0, 'dcValue2' => null, 'dcValue3' => 0]], - 'string(0) as number value as type boolean' => [['0'], 'boolean', 'SELECT WHERE `title` = :dcValue3', ['dcValue1' => '0', 'dcValue2' => null, 'dcValue3' => '0']], - - 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` = 42', []], - 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` = 42', []], - 'integer(negative)value as type double' => [-5, 'double', 'SELECT WHERE `title` = -5', []], - 'string(negative) as number value as type double' => ['-5', 'double', 'SELECT WHERE `title` = -5', []], - 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` = 42.5', []], - 'string float value as type double' => ['42.5', 'double', 'SELECT WHERE `title` = 42.5', []], - 'float value (2 decimal w 00) as type double' => [42.00, 'double', 'SELECT WHERE `title` = 42', []], - 'float value (2 decimal w 50) as type double' => [42.50, 'double', 'SELECT WHERE `title` = 42.5', []], - 'float value (2 decimal w 55) as type double' => [42.55, 'double', 'SELECT WHERE `title` = 42.55', []], - 'string float value (2 decimal) as type double' => ['42.50', 'double', 'SELECT WHERE `title` = 42.5', []], - 'comma value as type double' => ['42,50', 'double', 'SELECT WHERE `title` = 42.5', []], - 'comma value (2 decimal) as type double' => ['42,50', 'double', 'SELECT WHERE `title` = 42.5', []], - 'string as type double' => ['foo', 'double', 'SELECT WHERE `title` = 0', []], - - 'comma value as type date' => ['2017-06-26', 'date', 'SELECT WHERE `title` = 1498420800', []], - - 'comma value as type time' => ['18:30', 'time', 'SELECT WHERE `title` = 66600', []], - - 'string as number value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` = 1483221600', []], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleEqualQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleEqualQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "equal", - "value": "foo" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForMultipleEqualsQueryDataProvider() : array - { - return [ - 'foo, bar, int and date' => [ - '{ - "condition": "AND", - "rules": [ - { - "id": "input_1", - "field": "input_1", - "type": "string", - "input": "text", - "operator": "equal", - "value": "foo" - }, - { - "id": "input_1", - "field": "input_1", - "type": "string", - "input": "text", - "operator": "equal", - "value": "bar" - }, - { - "condition": "OR", - "rules": [ - { - "id": "input_9", - "field": "input_9", - "type": "integer", - "input": "number", - "operator": "equal", - "value": "42" - }, - { - "id": "inputdatetime_2", - "field": "inputdatetime_2", - "type": "date", - "input": "text", - "operator": "equal", - "value": "2017-06-26" - } - ] - } - ], - "valid": true - }', - 'SELECT WHERE ((`input_9` = 42) OR (`inputdatetime_2` = 1498420800)) AND ((`input_1` = :dcValue1) AND (`input_1` = :dcValue2))', - ['dcValue1' => 'foo', 'dcValue2' => 'bar'] - ], - - 'double, time, boolean, datetime' => [ - '{ - "condition": "AND", - "rules": [ - { - "id": "input_8", - "field": "input_8", - "type": "double", - "input": "number", - "operator": "equal", - "value": "42.42" - }, - { - "condition": "AND", - "rules": [ - { - "id": "inputdatetime_5", - "field": "inputdatetime_5", - "type": "time", - "input": "text", - "operator": "equal", - "value": "16:30" - }, - { - "id": "checkbox_2", - "field": "checkbox_2", - "type": "boolean", - "input": "checkbox", - "operator": "equal", - "value": ["1"] - } - ] - }, - { - "condition": "AND", - "rules": [ - { - "id": "inputdatetime_4", - "field": "inputdatetime_4", - "type": "datetime", - "input": "text", - "operator": "equal", - "value": "2017-06-28 16:30" - } - ] - } - ], - "valid": true - }', - 'SELECT WHERE ((`inputdatetime_5` = 59400) AND (`checkbox_2` = :dcValue3)) AND (`inputdatetime_4` = 1498653000) AND (`input_8` = 42.42)', - ['dcValue1' => '1', 'dcValue2' => null, 'dcValue3' => '1'] - ], - - 'simple group' => [ - '{ - "condition": "AND", - "rules": [ - { - "condition": "AND", - "rules": [ - { - "id": "header", - "field": "header", - "type": "string", - "input": "text", - "operator": "equal", - "value": "humbel" - }, - { - "id": "header", - "field": "header", - "type": "string", - "input": "text", - "operator": "equal", - "value": "bumbel" - } - ] - } - ], - "valid": true - }', - 'SELECT WHERE (`header` = :dcValue1) AND (`header` = :dcValue2)', - ['dcValue1' => 'humbel', 'dcValue2' => 'bumbel'] - ], - - 'or condition' => [ - '{ - "condition": "OR", - "rules": [ - { - "id": "header", - "field": "header", - "type": "string", - "input": "text", - "operator": "equal", - "value": "humbel" - }, - { - "id": "header", - "field": "header", - "type": "string", - "input": "text", - "operator": "equal", - "value": "bumbel" - } - ], - "valid": true - }', - 'SELECT WHERE (`header` = :dcValue1) OR (`header` = :dcValue2)', - ['dcValue1' => 'humbel', 'dcValue2' => 'bumbel'] - ] - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForMultipleEqualsQueryDataProvider - * - * @param $multipleRules - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForMultipleEqualsQuery($multipleRules, $expectedSQL, $expectedParameters): void - { - $query = json_decode($multipleRules); - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleNotEqualQueryDataProvider() : array - { - return [ - 'integer value as type string' => [42, 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => 42]], - 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => 42]], - 'float value as type string' => [42.5, 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => 42.5]], - 'string float value as type string' => ['42.5', 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => 42.5]], - 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => '42,5']], - 'string as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => 'foo']], - - 'integer value as type integer' => [42, 'integer', 'SELECT WHERE `title` <> 42', []], - 'string as number value as type integer' => ['42', 'integer', 'SELECT WHERE `title` <> 42', []], - 'integer(negative) value as type integer' => [-5, 'integer', 'SELECT WHERE `title` <> -5', []], - 'string(negative) as number value as type integer' => ['-5', 'integer', 'SELECT WHERE `title` <> -5', []], - - 'integer(1) value as type boolean' => [[1], 'boolean', 'SELECT WHERE `title` <> :dcValue3', ['dcValue1' => 1, 'dcValue2' => null, 'dcValue3' => 1]], - 'string(1) as number value as type boolean' => [['1'], 'boolean', 'SELECT WHERE `title` <> :dcValue3', ['dcValue1' => 1, 'dcValue2' => null, 'dcValue3' => 1]], - 'integer(0) value as type boolean' => [[0], 'boolean', 'SELECT WHERE `title` <> :dcValue3', ['dcValue1' => 0, 'dcValue2' => null, 'dcValue3' => 0]], - 'string(0) as number value as type boolean' => [['0'], 'boolean', 'SELECT WHERE `title` <> :dcValue3', ['dcValue1' => 0, 'dcValue2' => null, 'dcValue3' => 0]], - - 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` <> 42', []], - 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` <> 42', []], - 'integer(negative)value as type double' => [-5, 'double', 'SELECT WHERE `title` <> -5', []], - 'string(negative) as number value as type double' => ['-5', 'double', 'SELECT WHERE `title` <> -5', []], - 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` <> 42.5', []], - 'string float value as type double' => ['42.5', 'double', 'SELECT WHERE `title` <> 42.5', []], - 'float value (2 decimal w 00) as type double' => [42.00, 'double', 'SELECT WHERE `title` <> 42', []], - 'float value (2 decimal w 50) as type double' => [42.50, 'double', 'SELECT WHERE `title` <> 42.5', []], - 'float value (2 decimal w 55) as type double' => [42.55, 'double', 'SELECT WHERE `title` <> 42.55', []], - 'string float value (2 decimal) as type double' => ['42.50', 'double', 'SELECT WHERE `title` <> 42.5', []], - 'comma value as type double' => ['42,50', 'double', 'SELECT WHERE `title` <> 42.5', []], - 'comma value (2 decimal) as type double' => ['42,50', 'double', 'SELECT WHERE `title` <> 42.5', []], - - 'comma value as type date' => ['2017-06-26', 'date', 'SELECT WHERE `title` <> 1498420800', []], - - 'comma value as type time' => ['18:30', 'time', 'SELECT WHERE `title` <> 66600', []], - - 'string as number value as type datetime' => ['2017-01-21 00:00', 'datetime', 'SELECT WHERE `title` <> 1484949600', []], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleNotEqualQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleNotEqualQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "not_equal", - "value": "foo" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleInQueryDataProvider() : array - { - return [ - 'integer value as type string' => [42, 'string', 'SELECT WHERE `title` IN (:dcValue2)', ['dcValue2' => 42, 'dcValue1' => '42']], - 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` IN (:dcValue2)', ['dcValue2' => 42, 'dcValue1' => '42']], - 'float value as type string' => [42.5, 'string', 'SELECT WHERE `title` IN (:dcValue2)', ['dcValue2' => 42.5, 'dcValue1' => 42.5]], - 'two float values as type string' => ['42.5;50.5', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3)', ['dcValue2' => '42.5', 'dcValue3' => '50.5', 'dcValue1' => '42.5;50.5']], - 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` IN (:dcValue2)', ['dcValue2' => '42,5', 'dcValue1' => '42,5']], - 'two comma values as type string with ; as delimiter' => ['42,5;5,5', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5;5,5']], - 'two comma values as type string with # as delimiter' => ['42,5#5,5', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5#5,5']], - 'two comma values as type string with | as delimiter' => ['42,5|5,5', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5|5,5']], - 'multiple comma values as type string with mixed delimiters' => ['42,5;5,5#6,6|7,7', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3,:dcValue4,:dcValue5)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue4' => '6,6', 'dcValue5' => '7,7', 'dcValue1' => '42,5;5,5#6,6|7,7']], - 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` IN (:dcValue2)', ['dcValue2' => 'foo', 'dcValue1' => 'foo']], - 'string(2 words) as string value as type string' => ['foo;bar', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3)', ['dcValue2' => 'foo', 'dcValue3' => 'bar', 'dcValue1' => 'foo;bar']], - 'string(3 words) as string value as type string' => ['foo;bar;dong', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3,:dcValue4)', ['dcValue2' => 'foo', 'dcValue3' => 'bar', 'dcValue4' => 'dong', 'dcValue1' => 'foo;bar;dong']], - 'mixed values as type string' => ['foo;42,5;dong', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3,:dcValue4)', ['dcValue2' => 'foo', 'dcValue3' => '42,5', 'dcValue4' => 'dong', 'dcValue1' => 'foo;42,5;dong']], - - 'integer value as type integer' => [42, 'integer', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => '42']], - 'string as number value as type integer' => ['42', 'integer', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => '42']], - - 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => '42.5']], - 'string float value as type double' => ['42.5', 'double', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => '42.5']], - 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => '42.5']], - - 'comma value as type date' => ['2017-06-26', 'date', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => 1498420800]], - - 'comma value as type time' => ['18:30', 'time', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => 66600]], - - 'string as number value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => 1483221600]], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleInQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleInQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "in", - "value": "foo, bar" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleNotInQueryDataProvider() : array - { - return [ - 'integer value as type string' => [42, 'string', 'SELECT WHERE `title` NOT IN (:dcValue2)', ['dcValue2' => 42, 'dcValue1' => 42]], - 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2)', ['dcValue2' => 42, 'dcValue1' => '42']], - 'float value as type string' => [42.5, 'string', 'SELECT WHERE `title` NOT IN (:dcValue2)', ['dcValue2' => 42.5, 'dcValue1' => 42.5]], - 'two float values as type string' => ['42.5;50.5', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3)', ['dcValue2' => '42.5', 'dcValue3' => '50.5', 'dcValue1' => '42.5;50.5']], - 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2)', ['dcValue2' => '42,5', 'dcValue1' => '42,5']], - 'two comma values as type string with ; as delimiter' => ['42,5;5,5', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5;5,5']], - 'two comma values as type string with # as delimiter' => ['42,5#5,5', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5#5,5']], - 'two comma values as type string with | as delimiter' => ['42,5|5,5', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5|5,5']], - 'multiple comma values as type string with mixed delimiters' => ['42,5;5,5#6,6|7,7', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3,:dcValue4,:dcValue5)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue4' => '6,6', 'dcValue5' => '7,7', 'dcValue1' => '42,5;5,5#6,6|7,7']], - 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2)', ['dcValue2' => 'foo', 'dcValue1' => 'foo']], - 'string(2 words) as string value as type string' => ['foo;bar', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3)', ['dcValue2' => 'foo', 'dcValue3' => 'bar', 'dcValue1' => 'foo;bar']], - 'string(3 words) as string value as type string' => ['foo;bar;dong', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3,:dcValue4)', ['dcValue2' => 'foo', 'dcValue3' => 'bar', 'dcValue4' => 'dong', 'dcValue1' => 'foo;bar;dong']], - 'mixed values as type string' => ['foo;42,5;dong', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3,:dcValue4)', ['dcValue2' => 'foo', 'dcValue3' => '42,5', 'dcValue4' => 'dong', 'dcValue1' => 'foo;42,5;dong']], - - 'integer value as type integer' => [42, 'integer', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => '42']], - 'string as number value as type integer' => ['42', 'integer', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => '42']], - - 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => '42.5']], - 'string float value as type double' => ['42.5', 'double', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => '42.5']], - 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => '42.5']], - - 'comma value as type date' => ['2017-06-26', 'date', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => 1498420800]], - - 'comma value as type time' => ['18:30', 'time', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => 66600]], - - 'string as number value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => 1483221600]], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleNotInQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleNotInQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "not_in", - "value": "foo, bar" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleBeginsQueryDataProvider() : array - { - return [ - 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` LIKE \'42%\'', ['dcValue1' => 42]], - 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` LIKE \'42,5%\'', ['dcValue1' => '42,5']], - 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` LIKE \'foo%\'', ['dcValue1' => 'foo']], - 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` LIKE \'foo bar%\'', ['dcValue1' => 'foo bar']], - 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` LIKE \'foo\\\\%bar%\'', ['dcValue1' => 'foo%bar']], - 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` LIKE \'foo\\\\_bar%\'', ['dcValue1' => 'foo_bar']], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleBeginsQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleBeginsQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "begins_with", - "value": "foo" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleNotBeginsQueryDataProvider() : array - { - return [ - 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` NOT LIKE \'42%\'', ['dcValue1' => '42']], - 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` NOT LIKE \'42,5%\'', ['dcValue1' => '42,5']], - 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` NOT LIKE \'foo%\'', ['dcValue1' => 'foo']], - 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` NOT LIKE \'foo bar%\'', ['dcValue1' => 'foo bar']], - 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` NOT LIKE \'foo\\\\%bar%\'', ['dcValue1' => 'foo%bar']], - 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` NOT LIKE \'foo\\\\_bar%\'', ['dcValue1' => 'foo_bar']], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleNotBeginsQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleNotBeginsQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "not_begins_with", - "value": "foo" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleContainsQueryDataProvider() : array - { - return [ - 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` LIKE \'%42%\'', ['dcValue1' => '42']], - 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` LIKE \'%42,5%\'', ['dcValue1' => '42,5']], - 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` LIKE \'%foo%\'', ['dcValue1' => 'foo']], - 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` LIKE \'%foo bar%\'', ['dcValue1' => 'foo bar']], - 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` LIKE \'%foo\\\\%bar%\'', ['dcValue1' => 'foo%bar']], - 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` LIKE \'%foo\\\\_bar%\'', ['dcValue1' => 'foo_bar']], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleContainsQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleContainsQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "contains", - "value": "foo" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleNotContainsQueryDataProvider() : array - { - return [ - 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` NOT LIKE \'%42%\'', ['dcValue1' => '42']], - 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` NOT LIKE \'%42,5%\'', ['dcValue1' => '42,5']], - 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo%\'', ['dcValue1' => 'foo']], - 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo bar%\'', ['dcValue1' => 'foo bar']], - 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo\\\\%bar%\'', ['dcValue1' => 'foo%bar']], - 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo\\\\_bar%\'', ['dcValue1' => 'foo_bar']], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleNotContainsQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleNotContainsQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "not_contains", - "value": "foo" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleEndsQueryDataProvider() : array - { - return [ - 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` LIKE \'%42\'', ['dcValue1' => '42']], - 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` LIKE \'%42,5\'', ['dcValue1' => '42,5']], - 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` LIKE \'%foo\'', ['dcValue1' => 'foo']], - 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` LIKE \'%foo bar\'', ['dcValue1' => 'foo bar']], - 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` LIKE \'%foo\\\\%bar\'', ['dcValue1' => 'foo%bar']], - 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` LIKE \'%foo\\\\_bar\'', ['dcValue1' => 'foo_bar']], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleEndsQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleEndsQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "ends_with", - "value": "foo" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleNotEndsQueryDataProvider() : array - { - return [ - 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` NOT LIKE \'%42\'', ['dcValue1' => '42']], - 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` NOT LIKE \'%42,5\'', ['dcValue1' => '42,5']], - 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo\'', ['dcValue1' => 'foo']], - 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo bar\'', ['dcValue1' => 'foo bar']], - 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo\\\\%bar\'', ['dcValue1' => 'foo%bar']], - 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo\\\\_bar\'', ['dcValue1' => 'foo_bar']], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleNotEndsQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleNotEndsQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "not_ends_with", - "value": "foo" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @test - */ - public function parseReturnsValidWhereClauseForSimpleEmptyQuery(): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "is_empty" - } - ], - "valid": true - }'); - $expectedResult = 'SELECT WHERE (`title` = \'\') OR (`title` IS NULL)'; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedResult, $queryBuilder->getSQL()); - } - - /** - * @test - */ - public function parseReturnsValidWhereClauseForSimpleNotEmptyQuery(): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "is_not_empty" - } - ], - "valid": true - }'); - $expectedResult = 'SELECT WHERE (`title` <> \'\') AND (`title` IS NOT NULL)'; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedResult, $queryBuilder->getSQL()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleNullQueryDataProvider() : array - { - return [ - 'type string' => ['string'], - 'type integer' => ['integer'], - 'type double' => ['double'], - 'type date' => ['date'], - 'type datetime' => ['datetime'], - 'type time' => ['time'], - 'type boolean' => ['boolean'], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleNullQueryDataProvider - * - * @param $type - */ - public function parseReturnsValidWhereClauseForSimpleNullQuery($type): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "is_null" - } - ], - "valid": true - }'); - $query->rules[0]->type = $type; - $expectedResult = 'SELECT WHERE `title` IS NULL'; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedResult, $queryBuilder->getSQL()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleNotNullQueryDataProvider() : array - { - return [ - 'type string' => ['string'], - 'type integer' => ['integer'], - 'type double' => ['double'], - 'type date' => ['date'], - 'type datetime' => ['datetime'], - 'type time' => ['time'], - 'type boolean' => ['boolean'], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleNotNullQueryDataProvider - * - * @param $type - */ - public function parseReturnsValidWhereClauseForSimpleNotNullQuery($type): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "text", - "operator": "is_not_null" - } - ], - "valid": true - }'); - $query->rules[0]->type = $type; - $expectedResult = 'SELECT WHERE `title` IS NOT NULL'; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedResult, $queryBuilder->getSQL()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleLessQueryDataProvider() : array - { - return [ - 'integer value as type integer' => [42, 'integer', 'SELECT WHERE `title` < 42', []], - 'float value as type integer' => [42.5, 'integer', 'SELECT WHERE `title` < 42', []], - 'comma value as type integer' => ['42,5', 'integer', 'SELECT WHERE `title` < 42', []], - 'string as number value as type integer' => ['42', 'integer', 'SELECT WHERE `title` < 42', []], - 'string as string value as type integer' => ['foo', 'integer', 'SELECT WHERE `title` < 0', []], - - 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` < 42', []], - 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` < 42.5', []], - 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` < 42.5', []], - 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` < 42', []], - - 'string as date value as type date' => ['2017-01-01', 'date', 'SELECT WHERE `title` < 1483221600', []], - - 'string as type time' => ['16:30', 'time', 'SELECT WHERE `title` < 59400', []], - - 'string as datetime value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` < 1483221600', []], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleLessQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleLessQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "integer", - "operator": "less", - "value": "42" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleLessOrEqualQueryDataProvider() : array - { - return [ - 'integer value as integer' => [42, 'integer', 'SELECT WHERE `title` <= 42', []], - 'float value as integer' => [42.5, 'integer', 'SELECT WHERE `title` <= 42', []], - 'comma value as integer' => ['42,5', 'integer', 'SELECT WHERE `title` <= 42', []], - 'string as number value as integer' => ['42', 'integer', 'SELECT WHERE `title` <= 42', []], - 'string as string value as integer' => ['foo', 'integer', 'SELECT WHERE `title` <= 0', []], - - 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` <= 42', []], - 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` <= 42.5', []], - 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` <= 42.5', []], - 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` <= 42', []], - - 'string as date value as type date' => ['2017-01-01', 'date', 'SELECT WHERE `title` <= 1483221600', []], - - 'string as type time' => ['16:30', 'time', 'SELECT WHERE `title` <= 59400', []], - - 'string as datetime value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` <= 1483221600', []], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleLessOrEqualQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleLessOrEqualQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "integer", - "operator": "less_or_equal", - "value": "42" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleGreaterQueryDataProvider() : array - { - return [ - 'integer value as integer' => [42, 'integer', 'SELECT WHERE `title` > 42', []], - 'float value as integer' => [42.5, 'integer', 'SELECT WHERE `title` > 42', []], - 'comma value as integer' => ['42,5', 'integer', 'SELECT WHERE `title` > 42', []], - 'string as number value as integer' => ['42', 'integer', 'SELECT WHERE `title` > 42', []], - 'string as string value as integer' => ['foo', 'integer', 'SELECT WHERE `title` > 0', []], - - 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` > 42', []], - 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` > 42.5', []], - 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` > 42.5', []], - 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` > 42', []], - - 'string as date value as type date' => ['2017-01-01', 'date', 'SELECT WHERE `title` > 1483221600', []], - - 'string as type time' => ['16:30', 'time', 'SELECT WHERE `title` > 59400', []], - - 'string as datetime value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` > 1483221600', []], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleGreaterQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleGreaterQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "integer", - "operator": "greater", - "value": "42" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleGreaterOrEqualQueryDataProvider() : array - { - return [ - 'integer value as integer' => [42, 'integer', 'SELECT WHERE `title` >= 42', []], - 'float value as integer' => [42.5, 'integer', 'SELECT WHERE `title` >= 42', []], - 'comma value as integer' => ['42,5', 'integer', 'SELECT WHERE `title` >= 42', []], - 'string as number value as integer' => ['42', 'integer', 'SELECT WHERE `title` >= 42', []], - 'string as string value as integer' => ['foo', 'integer', 'SELECT WHERE `title` >= 0', []], - - 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` >= 42', []], - 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` >= 42.5', []], - 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` >= 42.5', []], - 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` >= 42', []], - - 'string as date value as type date' => ['2017-01-01', 'date', 'SELECT WHERE `title` >= 1483221600', []], - - 'string as type time' => ['16:30', 'time', 'SELECT WHERE `title` >= 59400', []], - - 'string as datetime value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` >= 1483221600', []], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleGreaterOrEqualQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleGreaterOrEqualQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "integer", - "operator": "greater_or_equal", - "value": "42" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleBetweenQueryDataProvider() : array - { - return [ - 'integer value as integer' => [[42, 62], 'integer', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], - 'float value as integer' => [[42.5, 62.5], 'integer', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], - 'comma value as integer' => [['42,5', '62,5'], 'integer', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], - 'string as number value as integer' => [['42', '62'], 'integer', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], - 'string as string value as integer' => [['foo', 'bar'], 'integer', 'SELECT WHERE (`title` > 0) AND (`title` < 0)', []], - - 'integer value as type double' => [[42, 62], 'double', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], - 'float value as type double' => [[42.5, 62.5], 'double', 'SELECT WHERE (`title` > 42.5) AND (`title` < 62.5)', []], - 'comma value as type double' => [['42,5', '62,5'], 'double', 'SELECT WHERE (`title` > 42.5) AND (`title` < 62.5)', []], - 'string as number value as type double' => [['42', '62'], 'double', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], - - 'string as date value as type date' => [['2017-01-01', '2017-06-30'], 'datetime', 'SELECT WHERE (`title` > 1483221600) AND (`title` < 1498766400)', []], - - 'string as type time' => [['16:30', '18:30'], 'time', 'SELECT WHERE (`title` > 59400) AND (`title` < 66600)', []], - - 'string as datetime value as type datetime' => [['2017-01-01 00:00', '2017-06-30 23:59'], 'datetime', 'SELECT WHERE (`title` > 1483221600) AND (`title` < 1498852740)', []], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleBetweenQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleBetweenQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "integer", - "operator": "between", - "value": "42,62" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } - - /** - * @return array - */ - public function parseReturnsValidWhereClauseForSimpleNotBetweenQueryDataProvider() : array - { - return [ - 'integer value as integer' => [[42, 62], 'integer', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], - 'float value as integer' => [[42.5, 62.5], 'integer', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], - 'comma value as integer' => [['42,5', '62,5'], 'integer', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], - 'string as number value as integer' => [['42', '62'], 'integer', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], - 'string as string value as integer' => [['foo', 'bar'], 'integer', 'SELECT WHERE (`title` < 0) OR (`title` > 0)', []], - - 'integer value as type double' => [[42, 62], 'double', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], - 'float value as type double' => [[42.5, 62.5], 'double', 'SELECT WHERE (`title` < 42.5) OR (`title` > 62.5)', []], - 'comma value as type double' => [['42,5', '62,5'], 'double', 'SELECT WHERE (`title` < 42.5) OR (`title` > 62.5)', []], - 'string as number value as type double' => [['42', '62'], 'double', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], - - 'string as date value as type date' => [['2017-01-01', '2017-06-30'], 'date', 'SELECT WHERE (`title` < 1483221600) OR (`title` > 1498766400)', []], - - 'string as type time' => [['16:30', '18:30'], 'time', 'SELECT WHERE (`title` < 59400) OR (`title` > 66600)', []], - - 'string as datetime value as type datetime' => [['2017-01-01 00:00', '2017-06-30 23:59'], 'datetime', 'SELECT WHERE (`title` < 1483221600) OR (`title` > 1498852740)', []], - ]; - } - - /** - * @test - * @dataProvider parseReturnsValidWhereClauseForSimpleNotBetweenQueryDataProvider - * - * @param $number - * @param $type - * @param $expectedSQL - * @param $expectedParameters - */ - public function parseReturnsValidWhereClauseForSimpleNotBetweenQuery($number, $type, $expectedSQL, $expectedParameters): void - { - $query = json_decode('{ - "condition": "AND", - "rules": [ - { - "id": "title", - "field": "title", - "type": "string", - "input": "integer", - "operator": "not_between", - "value": "42,62" - } - ], - "valid": true - }'); - $query->rules[0]->value = $number; - $query->rules[0]->type = $type; - $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); - self::assertEquals($expectedSQL, $queryBuilder->getSQL()); - self::assertEquals($expectedParameters, $queryBuilder->getParameters()); - } -} diff --git a/composer.json b/composer.json index 7346fca..89e2869 100644 --- a/composer.json +++ b/composer.json @@ -64,20 +64,20 @@ ] }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "ext-json": "*", "ext-pdo": "*", "psr/http-message": "^1.0.0", - "typo3/cms-backend": "^10.1", - "typo3/cms-core": "^10.1", - "typo3/cms-recordlist": "^10.1" + "typo3/cms-backend": "^11.0", + "typo3/cms-core": "^11.0", + "typo3/cms-recordlist": "^11.0" }, "require-dev": { "overtrue/phplint": "^1.1", "bk2k/extension-helper": "^1.0", "friendsofphp/php-cs-fixer": "^2.12", "roave/security-advisories": "dev-master", - "typo3/testing-framework": "^5.0" + "typo3/testing-framework": "^6.0" }, "minimum-stability": "dev", "prefer-stable": true diff --git a/ext_emconf.php b/ext_emconf.php index dfa0845..3e80f46 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -15,10 +15,10 @@ 'clearCacheOnLoad' => 0, 'author' => 'TYPO3 GmbH', 'author_email' => 'info@typo3.com', - 'version' => '10.4.0', + 'version' => '11.0.0', 'constraints' => [ 'depends' => [ - 'typo3' => '10.0.0 - 10.5.99', + 'typo3' => '11.0.0 - 11.0.99', ], 'conflicts' => [], 'suggests' => [], From 134ad0cf4b6f175482853f7e87dcf57bb72e1606 Mon Sep 17 00:00:00 2001 From: Henrik Elsner Date: Sat, 16 Jan 2021 20:12:01 +0100 Subject: [PATCH 2/9] [TASK] Change TYPO3_MODE const into TYPO3 --- ext_localconf.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ext_localconf.php b/ext_localconf.php index 677dc19..0626ac8 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -7,9 +7,7 @@ * LICENSE file that was distributed with this source code. */ -if (!defined('TYPO3_MODE')) { - die('Access denied.'); -} +defined('TYPO3_MODE') || die(); // PageRenderer Hook to add CSS and JS modules $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess'][] = From fc25aaf775fb873dc0d3f5c524719ad919d0023b Mon Sep 17 00:00:00 2001 From: Henrik Elsner Date: Sat, 16 Jan 2021 20:14:19 +0100 Subject: [PATCH 3/9] [CLEANUP] Remove sql fields that are provided by TCA --- ext_tables.sql | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext_tables.sql b/ext_tables.sql index 1067c4e..2c811aa 100644 --- a/ext_tables.sql +++ b/ext_tables.sql @@ -9,8 +9,6 @@ CREATE TABLE sys_querybuilder ( queryname varchar(255) DEFAULT '' NOT NULL, where_parts text, user varchar(255) DEFAULT '' NOT NULL, - hidden tinyint(1) unsigned DEFAULT '0' NOT NULL, - deleted tinyint(1) unsigned DEFAULT '0' NOT NULL, PRIMARY KEY (uid) ); From 9b1d82499621974ae23fa4dce5113090e830190b Mon Sep 17 00:00:00 2001 From: Henrik Elsner Date: Sat, 16 Jan 2021 20:18:25 +0100 Subject: [PATCH 4/9] [TASK] Readd accidentally dropped tests --- Tests/Functional/FunctionalTestCase.php | 64 + Tests/Functional/Parser/QueryParserTest.php | 1292 +++++++++++++++++++ 2 files changed, 1356 insertions(+) create mode 100644 Tests/Functional/FunctionalTestCase.php create mode 100644 Tests/Functional/Parser/QueryParserTest.php diff --git a/Tests/Functional/FunctionalTestCase.php b/Tests/Functional/FunctionalTestCase.php new file mode 100644 index 0000000..76573c8 --- /dev/null +++ b/Tests/Functional/FunctionalTestCase.php @@ -0,0 +1,64 @@ +scenarioDataSetDirectory . $scenarioName . '.csv'; + $scenarioFileName = GeneralUtility::getFileAbsFileName($scenarioFileName); + $this->importCSVDataSet($scenarioFileName); + } + + /** + * @param string $scenarioName + */ + protected function importAssertCSVScenario(string $scenarioName = ''): void + { + $scenarioFileName = $this->assertionDataSetDirectory . $scenarioName . '.csv'; + $scenarioFileName = GeneralUtility::getFileAbsFileName($scenarioFileName); + $this->assertCSVDataSet($scenarioFileName); + } +} diff --git a/Tests/Functional/Parser/QueryParserTest.php b/Tests/Functional/Parser/QueryParserTest.php new file mode 100644 index 0000000..adc2f54 --- /dev/null +++ b/Tests/Functional/Parser/QueryParserTest.php @@ -0,0 +1,1292 @@ +originalTimeZone = date_default_timezone_get(); + date_default_timezone_set('Europe/Berlin'); + $this->subject = new QueryParser(); + } + + /** + * + */ + protected function tearDown(): void + { + date_default_timezone_set($this->originalTimeZone); + parent::tearDown(); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleEqualQueryDataProvider() : array + { + return [ + 'integer value as type string' => [42, 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => 42]], + 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => 42]], + 'float value as type string' => [42.5, 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => 42.5]], + 'string float value as type string' => ['42.5', 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => 42.5]], + 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => '42,5']], + 'string as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` = :dcValue1', ['dcValue1' => 'foo']], + + 'integer value as type integer' => [42, 'integer', 'SELECT WHERE `title` = 42', []], + 'string as number value as type integer' => ['42', 'integer', 'SELECT WHERE `title` = 42', []], + 'integer(negative) value as type integer' => [-5, 'integer', 'SELECT WHERE `title` = -5', []], + 'string(negative) as number value as type integer' => ['-5', 'integer', 'SELECT WHERE `title` = -5', []], + + 'integer(1) value as type boolean' => [[1], 'boolean', 'SELECT WHERE `title` = :dcValue3', ['dcValue1' => 1, 'dcValue2' => null, 'dcValue3' => 1]], + 'string(1) as number value as type boolean' => [['1'], 'boolean', 'SELECT WHERE `title` = :dcValue3', ['dcValue1' => '1', 'dcValue2' => null, 'dcValue3' => '1']], + 'integer(0) value as type boolean' => [[0], 'boolean', 'SELECT WHERE `title` = :dcValue3', ['dcValue1' => 0, 'dcValue2' => null, 'dcValue3' => 0]], + 'string(0) as number value as type boolean' => [['0'], 'boolean', 'SELECT WHERE `title` = :dcValue3', ['dcValue1' => '0', 'dcValue2' => null, 'dcValue3' => '0']], + + 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` = 42', []], + 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` = 42', []], + 'integer(negative)value as type double' => [-5, 'double', 'SELECT WHERE `title` = -5', []], + 'string(negative) as number value as type double' => ['-5', 'double', 'SELECT WHERE `title` = -5', []], + 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` = 42.5', []], + 'string float value as type double' => ['42.5', 'double', 'SELECT WHERE `title` = 42.5', []], + 'float value (2 decimal w 00) as type double' => [42.00, 'double', 'SELECT WHERE `title` = 42', []], + 'float value (2 decimal w 50) as type double' => [42.50, 'double', 'SELECT WHERE `title` = 42.5', []], + 'float value (2 decimal w 55) as type double' => [42.55, 'double', 'SELECT WHERE `title` = 42.55', []], + 'string float value (2 decimal) as type double' => ['42.50', 'double', 'SELECT WHERE `title` = 42.5', []], + 'comma value as type double' => ['42,50', 'double', 'SELECT WHERE `title` = 42.5', []], + 'comma value (2 decimal) as type double' => ['42,50', 'double', 'SELECT WHERE `title` = 42.5', []], + 'string as type double' => ['foo', 'double', 'SELECT WHERE `title` = 0', []], + + 'comma value as type date' => ['2017-06-26', 'date', 'SELECT WHERE `title` = 1498420800', []], + + 'comma value as type time' => ['18:30', 'time', 'SELECT WHERE `title` = 66600', []], + + 'string as number value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` = 1483221600', []], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleEqualQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleEqualQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "equal", + "value": "foo" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForMultipleEqualsQueryDataProvider() : array + { + return [ + 'foo, bar, int and date' => [ + '{ + "condition": "AND", + "rules": [ + { + "id": "input_1", + "field": "input_1", + "type": "string", + "input": "text", + "operator": "equal", + "value": "foo" + }, + { + "id": "input_1", + "field": "input_1", + "type": "string", + "input": "text", + "operator": "equal", + "value": "bar" + }, + { + "condition": "OR", + "rules": [ + { + "id": "input_9", + "field": "input_9", + "type": "integer", + "input": "number", + "operator": "equal", + "value": "42" + }, + { + "id": "inputdatetime_2", + "field": "inputdatetime_2", + "type": "date", + "input": "text", + "operator": "equal", + "value": "2017-06-26" + } + ] + } + ], + "valid": true + }', + 'SELECT WHERE ((`input_9` = 42) OR (`inputdatetime_2` = 1498420800)) AND ((`input_1` = :dcValue1) AND (`input_1` = :dcValue2))', + ['dcValue1' => 'foo', 'dcValue2' => 'bar'] + ], + + 'double, time, boolean, datetime' => [ + '{ + "condition": "AND", + "rules": [ + { + "id": "input_8", + "field": "input_8", + "type": "double", + "input": "number", + "operator": "equal", + "value": "42.42" + }, + { + "condition": "AND", + "rules": [ + { + "id": "inputdatetime_5", + "field": "inputdatetime_5", + "type": "time", + "input": "text", + "operator": "equal", + "value": "16:30" + }, + { + "id": "checkbox_2", + "field": "checkbox_2", + "type": "boolean", + "input": "checkbox", + "operator": "equal", + "value": ["1"] + } + ] + }, + { + "condition": "AND", + "rules": [ + { + "id": "inputdatetime_4", + "field": "inputdatetime_4", + "type": "datetime", + "input": "text", + "operator": "equal", + "value": "2017-06-28 16:30" + } + ] + } + ], + "valid": true + }', + 'SELECT WHERE ((`inputdatetime_5` = 59400) AND (`checkbox_2` = :dcValue3)) AND (`inputdatetime_4` = 1498653000) AND (`input_8` = 42.42)', + ['dcValue1' => '1', 'dcValue2' => null, 'dcValue3' => '1'] + ], + + 'simple group' => [ + '{ + "condition": "AND", + "rules": [ + { + "condition": "AND", + "rules": [ + { + "id": "header", + "field": "header", + "type": "string", + "input": "text", + "operator": "equal", + "value": "humbel" + }, + { + "id": "header", + "field": "header", + "type": "string", + "input": "text", + "operator": "equal", + "value": "bumbel" + } + ] + } + ], + "valid": true + }', + 'SELECT WHERE (`header` = :dcValue1) AND (`header` = :dcValue2)', + ['dcValue1' => 'humbel', 'dcValue2' => 'bumbel'] + ], + + 'or condition' => [ + '{ + "condition": "OR", + "rules": [ + { + "id": "header", + "field": "header", + "type": "string", + "input": "text", + "operator": "equal", + "value": "humbel" + }, + { + "id": "header", + "field": "header", + "type": "string", + "input": "text", + "operator": "equal", + "value": "bumbel" + } + ], + "valid": true + }', + 'SELECT WHERE (`header` = :dcValue1) OR (`header` = :dcValue2)', + ['dcValue1' => 'humbel', 'dcValue2' => 'bumbel'] + ] + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForMultipleEqualsQueryDataProvider + * + * @param $multipleRules + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForMultipleEqualsQuery($multipleRules, $expectedSQL, $expectedParameters): void + { + $query = json_decode($multipleRules); + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleNotEqualQueryDataProvider() : array + { + return [ + 'integer value as type string' => [42, 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => 42]], + 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => 42]], + 'float value as type string' => [42.5, 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => 42.5]], + 'string float value as type string' => ['42.5', 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => 42.5]], + 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => '42,5']], + 'string as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` <> :dcValue1', ['dcValue1' => 'foo']], + + 'integer value as type integer' => [42, 'integer', 'SELECT WHERE `title` <> 42', []], + 'string as number value as type integer' => ['42', 'integer', 'SELECT WHERE `title` <> 42', []], + 'integer(negative) value as type integer' => [-5, 'integer', 'SELECT WHERE `title` <> -5', []], + 'string(negative) as number value as type integer' => ['-5', 'integer', 'SELECT WHERE `title` <> -5', []], + + 'integer(1) value as type boolean' => [[1], 'boolean', 'SELECT WHERE `title` <> :dcValue3', ['dcValue1' => 1, 'dcValue2' => null, 'dcValue3' => 1]], + 'string(1) as number value as type boolean' => [['1'], 'boolean', 'SELECT WHERE `title` <> :dcValue3', ['dcValue1' => 1, 'dcValue2' => null, 'dcValue3' => 1]], + 'integer(0) value as type boolean' => [[0], 'boolean', 'SELECT WHERE `title` <> :dcValue3', ['dcValue1' => 0, 'dcValue2' => null, 'dcValue3' => 0]], + 'string(0) as number value as type boolean' => [['0'], 'boolean', 'SELECT WHERE `title` <> :dcValue3', ['dcValue1' => 0, 'dcValue2' => null, 'dcValue3' => 0]], + + 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` <> 42', []], + 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` <> 42', []], + 'integer(negative)value as type double' => [-5, 'double', 'SELECT WHERE `title` <> -5', []], + 'string(negative) as number value as type double' => ['-5', 'double', 'SELECT WHERE `title` <> -5', []], + 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` <> 42.5', []], + 'string float value as type double' => ['42.5', 'double', 'SELECT WHERE `title` <> 42.5', []], + 'float value (2 decimal w 00) as type double' => [42.00, 'double', 'SELECT WHERE `title` <> 42', []], + 'float value (2 decimal w 50) as type double' => [42.50, 'double', 'SELECT WHERE `title` <> 42.5', []], + 'float value (2 decimal w 55) as type double' => [42.55, 'double', 'SELECT WHERE `title` <> 42.55', []], + 'string float value (2 decimal) as type double' => ['42.50', 'double', 'SELECT WHERE `title` <> 42.5', []], + 'comma value as type double' => ['42,50', 'double', 'SELECT WHERE `title` <> 42.5', []], + 'comma value (2 decimal) as type double' => ['42,50', 'double', 'SELECT WHERE `title` <> 42.5', []], + + 'comma value as type date' => ['2017-06-26', 'date', 'SELECT WHERE `title` <> 1498420800', []], + + 'comma value as type time' => ['18:30', 'time', 'SELECT WHERE `title` <> 66600', []], + + 'string as number value as type datetime' => ['2017-01-21 00:00', 'datetime', 'SELECT WHERE `title` <> 1484949600', []], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleNotEqualQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleNotEqualQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "not_equal", + "value": "foo" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleInQueryDataProvider() : array + { + return [ + 'integer value as type string' => [42, 'string', 'SELECT WHERE `title` IN (:dcValue2)', ['dcValue2' => 42, 'dcValue1' => '42']], + 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` IN (:dcValue2)', ['dcValue2' => 42, 'dcValue1' => '42']], + 'float value as type string' => [42.5, 'string', 'SELECT WHERE `title` IN (:dcValue2)', ['dcValue2' => 42.5, 'dcValue1' => 42.5]], + 'two float values as type string' => ['42.5;50.5', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3)', ['dcValue2' => '42.5', 'dcValue3' => '50.5', 'dcValue1' => '42.5;50.5']], + 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` IN (:dcValue2)', ['dcValue2' => '42,5', 'dcValue1' => '42,5']], + 'two comma values as type string with ; as delimiter' => ['42,5;5,5', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5;5,5']], + 'two comma values as type string with # as delimiter' => ['42,5#5,5', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5#5,5']], + 'two comma values as type string with | as delimiter' => ['42,5|5,5', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5|5,5']], + 'multiple comma values as type string with mixed delimiters' => ['42,5;5,5#6,6|7,7', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3,:dcValue4,:dcValue5)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue4' => '6,6', 'dcValue5' => '7,7', 'dcValue1' => '42,5;5,5#6,6|7,7']], + 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` IN (:dcValue2)', ['dcValue2' => 'foo', 'dcValue1' => 'foo']], + 'string(2 words) as string value as type string' => ['foo;bar', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3)', ['dcValue2' => 'foo', 'dcValue3' => 'bar', 'dcValue1' => 'foo;bar']], + 'string(3 words) as string value as type string' => ['foo;bar;dong', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3,:dcValue4)', ['dcValue2' => 'foo', 'dcValue3' => 'bar', 'dcValue4' => 'dong', 'dcValue1' => 'foo;bar;dong']], + 'mixed values as type string' => ['foo;42,5;dong', 'string', 'SELECT WHERE `title` IN (:dcValue2,:dcValue3,:dcValue4)', ['dcValue2' => 'foo', 'dcValue3' => '42,5', 'dcValue4' => 'dong', 'dcValue1' => 'foo;42,5;dong']], + + 'integer value as type integer' => [42, 'integer', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => '42']], + 'string as number value as type integer' => ['42', 'integer', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => '42']], + + 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => '42.5']], + 'string float value as type double' => ['42.5', 'double', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => '42.5']], + 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => '42.5']], + + 'comma value as type date' => ['2017-06-26', 'date', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => 1498420800]], + + 'comma value as type time' => ['18:30', 'time', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => 66600]], + + 'string as number value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` IN (:dcValue1)', ['dcValue1' => 1483221600]], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleInQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleInQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "in", + "value": "foo, bar" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleNotInQueryDataProvider() : array + { + return [ + 'integer value as type string' => [42, 'string', 'SELECT WHERE `title` NOT IN (:dcValue2)', ['dcValue2' => 42, 'dcValue1' => 42]], + 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2)', ['dcValue2' => 42, 'dcValue1' => '42']], + 'float value as type string' => [42.5, 'string', 'SELECT WHERE `title` NOT IN (:dcValue2)', ['dcValue2' => 42.5, 'dcValue1' => 42.5]], + 'two float values as type string' => ['42.5;50.5', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3)', ['dcValue2' => '42.5', 'dcValue3' => '50.5', 'dcValue1' => '42.5;50.5']], + 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2)', ['dcValue2' => '42,5', 'dcValue1' => '42,5']], + 'two comma values as type string with ; as delimiter' => ['42,5;5,5', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5;5,5']], + 'two comma values as type string with # as delimiter' => ['42,5#5,5', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5#5,5']], + 'two comma values as type string with | as delimiter' => ['42,5|5,5', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue1' => '42,5|5,5']], + 'multiple comma values as type string with mixed delimiters' => ['42,5;5,5#6,6|7,7', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3,:dcValue4,:dcValue5)', ['dcValue2' => '42,5', 'dcValue3' => '5,5', 'dcValue4' => '6,6', 'dcValue5' => '7,7', 'dcValue1' => '42,5;5,5#6,6|7,7']], + 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2)', ['dcValue2' => 'foo', 'dcValue1' => 'foo']], + 'string(2 words) as string value as type string' => ['foo;bar', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3)', ['dcValue2' => 'foo', 'dcValue3' => 'bar', 'dcValue1' => 'foo;bar']], + 'string(3 words) as string value as type string' => ['foo;bar;dong', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3,:dcValue4)', ['dcValue2' => 'foo', 'dcValue3' => 'bar', 'dcValue4' => 'dong', 'dcValue1' => 'foo;bar;dong']], + 'mixed values as type string' => ['foo;42,5;dong', 'string', 'SELECT WHERE `title` NOT IN (:dcValue2,:dcValue3,:dcValue4)', ['dcValue2' => 'foo', 'dcValue3' => '42,5', 'dcValue4' => 'dong', 'dcValue1' => 'foo;42,5;dong']], + + 'integer value as type integer' => [42, 'integer', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => '42']], + 'string as number value as type integer' => ['42', 'integer', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => '42']], + + 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => '42.5']], + 'string float value as type double' => ['42.5', 'double', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => '42.5']], + 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => '42.5']], + + 'comma value as type date' => ['2017-06-26', 'date', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => 1498420800]], + + 'comma value as type time' => ['18:30', 'time', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => 66600]], + + 'string as number value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` NOT IN (:dcValue1)', ['dcValue1' => 1483221600]], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleNotInQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleNotInQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "not_in", + "value": "foo, bar" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleBeginsQueryDataProvider() : array + { + return [ + 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` LIKE \'42%\'', ['dcValue1' => 42]], + 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` LIKE \'42,5%\'', ['dcValue1' => '42,5']], + 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` LIKE \'foo%\'', ['dcValue1' => 'foo']], + 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` LIKE \'foo bar%\'', ['dcValue1' => 'foo bar']], + 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` LIKE \'foo\\\\%bar%\'', ['dcValue1' => 'foo%bar']], + 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` LIKE \'foo\\\\_bar%\'', ['dcValue1' => 'foo_bar']], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleBeginsQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleBeginsQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "begins_with", + "value": "foo" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleNotBeginsQueryDataProvider() : array + { + return [ + 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` NOT LIKE \'42%\'', ['dcValue1' => '42']], + 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` NOT LIKE \'42,5%\'', ['dcValue1' => '42,5']], + 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` NOT LIKE \'foo%\'', ['dcValue1' => 'foo']], + 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` NOT LIKE \'foo bar%\'', ['dcValue1' => 'foo bar']], + 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` NOT LIKE \'foo\\\\%bar%\'', ['dcValue1' => 'foo%bar']], + 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` NOT LIKE \'foo\\\\_bar%\'', ['dcValue1' => 'foo_bar']], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleNotBeginsQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleNotBeginsQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "not_begins_with", + "value": "foo" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleContainsQueryDataProvider() : array + { + return [ + 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` LIKE \'%42%\'', ['dcValue1' => '42']], + 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` LIKE \'%42,5%\'', ['dcValue1' => '42,5']], + 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` LIKE \'%foo%\'', ['dcValue1' => 'foo']], + 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` LIKE \'%foo bar%\'', ['dcValue1' => 'foo bar']], + 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` LIKE \'%foo\\\\%bar%\'', ['dcValue1' => 'foo%bar']], + 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` LIKE \'%foo\\\\_bar%\'', ['dcValue1' => 'foo_bar']], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleContainsQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleContainsQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "contains", + "value": "foo" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleNotContainsQueryDataProvider() : array + { + return [ + 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` NOT LIKE \'%42%\'', ['dcValue1' => '42']], + 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` NOT LIKE \'%42,5%\'', ['dcValue1' => '42,5']], + 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo%\'', ['dcValue1' => 'foo']], + 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo bar%\'', ['dcValue1' => 'foo bar']], + 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo\\\\%bar%\'', ['dcValue1' => 'foo%bar']], + 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo\\\\_bar%\'', ['dcValue1' => 'foo_bar']], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleNotContainsQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleNotContainsQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "not_contains", + "value": "foo" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleEndsQueryDataProvider() : array + { + return [ + 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` LIKE \'%42\'', ['dcValue1' => '42']], + 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` LIKE \'%42,5\'', ['dcValue1' => '42,5']], + 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` LIKE \'%foo\'', ['dcValue1' => 'foo']], + 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` LIKE \'%foo bar\'', ['dcValue1' => 'foo bar']], + 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` LIKE \'%foo\\\\%bar\'', ['dcValue1' => 'foo%bar']], + 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` LIKE \'%foo\\\\_bar\'', ['dcValue1' => 'foo_bar']], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleEndsQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleEndsQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "ends_with", + "value": "foo" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleNotEndsQueryDataProvider() : array + { + return [ + 'string as number value as type string' => ['42', 'string', 'SELECT WHERE `title` NOT LIKE \'%42\'', ['dcValue1' => '42']], + 'comma value as type string' => ['42,5', 'string', 'SELECT WHERE `title` NOT LIKE \'%42,5\'', ['dcValue1' => '42,5']], + 'string(1 words) as string value as type string' => ['foo', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo\'', ['dcValue1' => 'foo']], + 'string(2 words) as string value as type string' => ['foo bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo bar\'', ['dcValue1' => 'foo bar']], + 'string(2 words) as string value as type string with %' => ['foo%bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo\\\\%bar\'', ['dcValue1' => 'foo%bar']], + 'string(2 words) as string value as type string with _' => ['foo_bar', 'string', 'SELECT WHERE `title` NOT LIKE \'%foo\\\\_bar\'', ['dcValue1' => 'foo_bar']], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleNotEndsQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleNotEndsQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "not_ends_with", + "value": "foo" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @test + */ + public function parseReturnsValidWhereClauseForSimpleEmptyQuery(): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "is_empty" + } + ], + "valid": true + }'); + $expectedResult = 'SELECT WHERE (`title` = \'\') OR (`title` IS NULL)'; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedResult, $queryBuilder->getSQL()); + } + + /** + * @test + */ + public function parseReturnsValidWhereClauseForSimpleNotEmptyQuery(): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "is_not_empty" + } + ], + "valid": true + }'); + $expectedResult = 'SELECT WHERE (`title` <> \'\') AND (`title` IS NOT NULL)'; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedResult, $queryBuilder->getSQL()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleNullQueryDataProvider() : array + { + return [ + 'type string' => ['string'], + 'type integer' => ['integer'], + 'type double' => ['double'], + 'type date' => ['date'], + 'type datetime' => ['datetime'], + 'type time' => ['time'], + 'type boolean' => ['boolean'], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleNullQueryDataProvider + * + * @param $type + */ + public function parseReturnsValidWhereClauseForSimpleNullQuery($type): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "is_null" + } + ], + "valid": true + }'); + $query->rules[0]->type = $type; + $expectedResult = 'SELECT WHERE `title` IS NULL'; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedResult, $queryBuilder->getSQL()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleNotNullQueryDataProvider() : array + { + return [ + 'type string' => ['string'], + 'type integer' => ['integer'], + 'type double' => ['double'], + 'type date' => ['date'], + 'type datetime' => ['datetime'], + 'type time' => ['time'], + 'type boolean' => ['boolean'], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleNotNullQueryDataProvider + * + * @param $type + */ + public function parseReturnsValidWhereClauseForSimpleNotNullQuery($type): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "text", + "operator": "is_not_null" + } + ], + "valid": true + }'); + $query->rules[0]->type = $type; + $expectedResult = 'SELECT WHERE `title` IS NOT NULL'; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedResult, $queryBuilder->getSQL()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleLessQueryDataProvider() : array + { + return [ + 'integer value as type integer' => [42, 'integer', 'SELECT WHERE `title` < 42', []], + 'float value as type integer' => [42.5, 'integer', 'SELECT WHERE `title` < 42', []], + 'comma value as type integer' => ['42,5', 'integer', 'SELECT WHERE `title` < 42', []], + 'string as number value as type integer' => ['42', 'integer', 'SELECT WHERE `title` < 42', []], + 'string as string value as type integer' => ['foo', 'integer', 'SELECT WHERE `title` < 0', []], + + 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` < 42', []], + 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` < 42.5', []], + 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` < 42.5', []], + 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` < 42', []], + + 'string as date value as type date' => ['2017-01-01', 'date', 'SELECT WHERE `title` < 1483221600', []], + + 'string as type time' => ['16:30', 'time', 'SELECT WHERE `title` < 59400', []], + + 'string as datetime value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` < 1483221600', []], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleLessQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleLessQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "integer", + "operator": "less", + "value": "42" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleLessOrEqualQueryDataProvider() : array + { + return [ + 'integer value as integer' => [42, 'integer', 'SELECT WHERE `title` <= 42', []], + 'float value as integer' => [42.5, 'integer', 'SELECT WHERE `title` <= 42', []], + 'comma value as integer' => ['42,5', 'integer', 'SELECT WHERE `title` <= 42', []], + 'string as number value as integer' => ['42', 'integer', 'SELECT WHERE `title` <= 42', []], + 'string as string value as integer' => ['foo', 'integer', 'SELECT WHERE `title` <= 0', []], + + 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` <= 42', []], + 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` <= 42.5', []], + 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` <= 42.5', []], + 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` <= 42', []], + + 'string as date value as type date' => ['2017-01-01', 'date', 'SELECT WHERE `title` <= 1483221600', []], + + 'string as type time' => ['16:30', 'time', 'SELECT WHERE `title` <= 59400', []], + + 'string as datetime value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` <= 1483221600', []], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleLessOrEqualQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleLessOrEqualQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "integer", + "operator": "less_or_equal", + "value": "42" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleGreaterQueryDataProvider() : array + { + return [ + 'integer value as integer' => [42, 'integer', 'SELECT WHERE `title` > 42', []], + 'float value as integer' => [42.5, 'integer', 'SELECT WHERE `title` > 42', []], + 'comma value as integer' => ['42,5', 'integer', 'SELECT WHERE `title` > 42', []], + 'string as number value as integer' => ['42', 'integer', 'SELECT WHERE `title` > 42', []], + 'string as string value as integer' => ['foo', 'integer', 'SELECT WHERE `title` > 0', []], + + 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` > 42', []], + 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` > 42.5', []], + 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` > 42.5', []], + 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` > 42', []], + + 'string as date value as type date' => ['2017-01-01', 'date', 'SELECT WHERE `title` > 1483221600', []], + + 'string as type time' => ['16:30', 'time', 'SELECT WHERE `title` > 59400', []], + + 'string as datetime value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` > 1483221600', []], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleGreaterQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleGreaterQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "integer", + "operator": "greater", + "value": "42" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleGreaterOrEqualQueryDataProvider() : array + { + return [ + 'integer value as integer' => [42, 'integer', 'SELECT WHERE `title` >= 42', []], + 'float value as integer' => [42.5, 'integer', 'SELECT WHERE `title` >= 42', []], + 'comma value as integer' => ['42,5', 'integer', 'SELECT WHERE `title` >= 42', []], + 'string as number value as integer' => ['42', 'integer', 'SELECT WHERE `title` >= 42', []], + 'string as string value as integer' => ['foo', 'integer', 'SELECT WHERE `title` >= 0', []], + + 'integer value as type double' => [42, 'double', 'SELECT WHERE `title` >= 42', []], + 'float value as type double' => [42.5, 'double', 'SELECT WHERE `title` >= 42.5', []], + 'comma value as type double' => ['42,5', 'double', 'SELECT WHERE `title` >= 42.5', []], + 'string as number value as type double' => ['42', 'double', 'SELECT WHERE `title` >= 42', []], + + 'string as date value as type date' => ['2017-01-01', 'date', 'SELECT WHERE `title` >= 1483221600', []], + + 'string as type time' => ['16:30', 'time', 'SELECT WHERE `title` >= 59400', []], + + 'string as datetime value as type datetime' => ['2017-01-01 00:00', 'datetime', 'SELECT WHERE `title` >= 1483221600', []], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleGreaterOrEqualQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleGreaterOrEqualQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "integer", + "operator": "greater_or_equal", + "value": "42" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleBetweenQueryDataProvider() : array + { + return [ + 'integer value as integer' => [[42, 62], 'integer', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], + 'float value as integer' => [[42.5, 62.5], 'integer', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], + 'comma value as integer' => [['42,5', '62,5'], 'integer', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], + 'string as number value as integer' => [['42', '62'], 'integer', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], + 'string as string value as integer' => [['foo', 'bar'], 'integer', 'SELECT WHERE (`title` > 0) AND (`title` < 0)', []], + + 'integer value as type double' => [[42, 62], 'double', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], + 'float value as type double' => [[42.5, 62.5], 'double', 'SELECT WHERE (`title` > 42.5) AND (`title` < 62.5)', []], + 'comma value as type double' => [['42,5', '62,5'], 'double', 'SELECT WHERE (`title` > 42.5) AND (`title` < 62.5)', []], + 'string as number value as type double' => [['42', '62'], 'double', 'SELECT WHERE (`title` > 42) AND (`title` < 62)', []], + + 'string as date value as type date' => [['2017-01-01', '2017-06-30'], 'datetime', 'SELECT WHERE (`title` > 1483221600) AND (`title` < 1498766400)', []], + + 'string as type time' => [['16:30', '18:30'], 'time', 'SELECT WHERE (`title` > 59400) AND (`title` < 66600)', []], + + 'string as datetime value as type datetime' => [['2017-01-01 00:00', '2017-06-30 23:59'], 'datetime', 'SELECT WHERE (`title` > 1483221600) AND (`title` < 1498852740)', []], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleBetweenQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleBetweenQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "integer", + "operator": "between", + "value": "42,62" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } + + /** + * @return array + */ + public function parseReturnsValidWhereClauseForSimpleNotBetweenQueryDataProvider() : array + { + return [ + 'integer value as integer' => [[42, 62], 'integer', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], + 'float value as integer' => [[42.5, 62.5], 'integer', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], + 'comma value as integer' => [['42,5', '62,5'], 'integer', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], + 'string as number value as integer' => [['42', '62'], 'integer', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], + 'string as string value as integer' => [['foo', 'bar'], 'integer', 'SELECT WHERE (`title` < 0) OR (`title` > 0)', []], + + 'integer value as type double' => [[42, 62], 'double', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], + 'float value as type double' => [[42.5, 62.5], 'double', 'SELECT WHERE (`title` < 42.5) OR (`title` > 62.5)', []], + 'comma value as type double' => [['42,5', '62,5'], 'double', 'SELECT WHERE (`title` < 42.5) OR (`title` > 62.5)', []], + 'string as number value as type double' => [['42', '62'], 'double', 'SELECT WHERE (`title` < 42) OR (`title` > 62)', []], + + 'string as date value as type date' => [['2017-01-01', '2017-06-30'], 'date', 'SELECT WHERE (`title` < 1483221600) OR (`title` > 1498766400)', []], + + 'string as type time' => [['16:30', '18:30'], 'time', 'SELECT WHERE (`title` < 59400) OR (`title` > 66600)', []], + + 'string as datetime value as type datetime' => [['2017-01-01 00:00', '2017-06-30 23:59'], 'datetime', 'SELECT WHERE (`title` < 1483221600) OR (`title` > 1498852740)', []], + ]; + } + + /** + * @test + * @dataProvider parseReturnsValidWhereClauseForSimpleNotBetweenQueryDataProvider + * + * @param $number + * @param $type + * @param $expectedSQL + * @param $expectedParameters + */ + public function parseReturnsValidWhereClauseForSimpleNotBetweenQuery($number, $type, $expectedSQL, $expectedParameters): void + { + $query = json_decode('{ + "condition": "AND", + "rules": [ + { + "id": "title", + "field": "title", + "type": "string", + "input": "integer", + "operator": "not_between", + "value": "42,62" + } + ], + "valid": true + }'); + $query->rules[0]->value = $number; + $query->rules[0]->type = $type; + $queryBuilder = $this->subject->parse($query, $this->getConnectionPool()->getQueryBuilderForTable($this->table)); + self::assertEquals($expectedSQL, $queryBuilder->getSQL()); + self::assertEquals($expectedParameters, $queryBuilder->getParameters()); + } +} From 1986be283362526518a2045e5c5c239292f67f19 Mon Sep 17 00:00:00 2001 From: Henrik Elsner Date: Sat, 16 Jan 2021 20:28:48 +0100 Subject: [PATCH 5/9] [FEAT] Implement DI --- Classes/Controller/QuerybuilderController.php | 32 ++++++++++---- Classes/Hooks/PageRenderer.php | 28 +++++++----- Classes/QueryBuilder.php | 44 ++++++++++++++++--- Configuration/Services.yaml | 32 ++++++++++++++ 4 files changed, 113 insertions(+), 23 deletions(-) create mode 100644 Configuration/Services.yaml diff --git a/Classes/Controller/QuerybuilderController.php b/Classes/Controller/QuerybuilderController.php index 92b81e8..fb9c512 100644 --- a/Classes/Controller/QuerybuilderController.php +++ b/Classes/Controller/QuerybuilderController.php @@ -12,18 +12,35 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; +use TYPO3\CMS\Core\Context\AspectInterface; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Context\UserAspect; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Http\JsonResponse; -use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Main script class for saving query */ class QuerybuilderController { + + /** + * @var ConnectionPool + */ + protected $connectionPool; + + /** + * @var Context + */ + protected $context; + + public function __construct(ConnectionPool $connectionPool, Context $context) + { + $this->connectionPool = $connectionPool; + $this->context = $context; + } + /** * @param ServerRequestInterface $request * @param ResponseInterface $response @@ -39,9 +56,9 @@ public function ajaxSaveQuery(ServerRequestInterface $request): ResponseInterfac $result->status = 'ok'; $requestParams = $request->getQueryParams(); - /** @var \TYPO3\CMS\Core\Database\Query\QueryBuilder $queryBuilder */ - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) - ->getQueryBuilderForTable('sys_querybuilder'); + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_querybuilder'); + $uid = (int)$requestParams['uid']; if ($uid > 0 && (int)$requestParams['override'] === 1) { $result->uid = $uid; @@ -83,8 +100,7 @@ public function ajaxGetRecentQueries(ServerRequestInterface $request): ResponseI { $requestParams = $request->getQueryParams(); /** @var QueryBuilder $queryBuilder */ - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) - ->getQueryBuilderForTable('sys_querybuilder'); + $queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_querybuilder'); $results = $queryBuilder ->select('uid', 'queryname', 'where_parts') @@ -106,8 +122,8 @@ public function ajaxGetRecentQueries(ServerRequestInterface $request): ResponseI * @return UserAspect * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException */ - protected function getBackendUserAspect(): UserAspect + protected function getBackendUserAspect(): AspectInterface { - return GeneralUtility::makeInstance(Context::class)->getAspect('backend.user'); + return $this->context->getAspect('backend.user'); } } diff --git a/Classes/Hooks/PageRenderer.php b/Classes/Hooks/PageRenderer.php index 0ea5003..adbafef 100644 --- a/Classes/Hooks/PageRenderer.php +++ b/Classes/Hooks/PageRenderer.php @@ -23,6 +23,16 @@ */ class PageRenderer { + /** + * @var \TYPO3\CMS\Core\Page\PageRenderer + */ + protected $pageRenderer; + + public function __construct(PageRenderer $pageRenderer) + { + $this->pageRenderer = $pageRenderer; + } + /** * @param array $params * @@ -37,13 +47,11 @@ public function renderPreProcess(array $params): void $table = $queryParams['table'] ?? ''; $route = $queryParams['route'] ?? ''; if (!empty($table) && $route === '/module/web/list') { - $pageRenderer = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Page\PageRenderer::class); - - $pageRenderer->addInlineLanguageLabelFile('EXT:querybuilder/Resources/Private/Language/querybuilder-js.xlf'); - $pageRenderer->addCssFile('EXT:querybuilder/Resources/Public/Css/query-builder.default.css'); - $pageRenderer->addCssFile('EXT:querybuilder/Resources/Public/Css/custom-query-builder.css'); + $this->pageRenderer->addInlineLanguageLabelFile('EXT:querybuilder/Resources/Private/Language/querybuilder-js.xlf'); + $this->pageRenderer->addCssFile('EXT:querybuilder/Resources/Public/Css/query-builder.default.css'); + $this->pageRenderer->addCssFile('EXT:querybuilder/Resources/Public/Css/custom-query-builder.css'); - $pageRenderer->addRequireJsConfiguration([ + $this->pageRenderer->addRequireJsConfiguration([ 'paths' => [ 'query-builder' => PathUtility::getAbsoluteWebPath('../typo3conf/ext/querybuilder/Resources/Public/JavaScript/query-builder.standalone'), 'query-builder/lang' => PathUtility::getAbsoluteWebPath('../typo3conf/ext/querybuilder/Resources/Public/JavaScript/Language'), @@ -56,16 +64,16 @@ public function renderPreProcess(array $params): void } $query = json_decode($queryParams['query'] ?? ''); - $pageRenderer->addJsInlineCode('tx_querybuilder_query', 'var tx_querybuilder_query = ' . json_encode($query) . ';'); + $this->pageRenderer->addJsInlineCode('tx_querybuilder_query', 'var tx_querybuilder_query = ' . json_encode($query) . ';'); $queryBuilder = GeneralUtility::makeInstance(QueryBuilder::class); $pageId = (int)$queryParams['id']; $filter = $queryBuilder->buildFilterFromTca($table, $pageId); - $pageRenderer->addJsInlineCode('tx_querybuilder_filter', 'var tx_querybuilder_filter = ' . json_encode($filter) . ';'); + $this->pageRenderer->addJsInlineCode('tx_querybuilder_filter', 'var tx_querybuilder_filter = ' . json_encode($filter) . ';'); - $pageRenderer->loadRequireJsModule($languageModule); - $pageRenderer->loadRequireJsModule('TYPO3/CMS/Querybuilder/QueryBuilder', 'function(QueryBuilder) { + $this->pageRenderer->loadRequireJsModule($languageModule); + $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Querybuilder/QueryBuilder', 'function(QueryBuilder) { QueryBuilder.initialize(tx_querybuilder_query, tx_querybuilder_filter); }'); } diff --git a/Classes/QueryBuilder.php b/Classes/QueryBuilder.php index 0de081d..751fe97 100644 --- a/Classes/QueryBuilder.php +++ b/Classes/QueryBuilder.php @@ -28,6 +28,40 @@ class QueryBuilder private const FORMAT_DATE = 'YYYY-MM-DD'; private const FORMAT_TIME = 'HH:mm'; + /** + * @var FilterFactory + */ + protected $filterFactory; + + /** + * @var PluginFactory + */ + protected $pluginFactory; + + /** + * @var ValidationFactory + */ + protected $validationFactory; + + /** + * @var TcaDatabaseRecord + */ + protected $formDataGroup; + + + public function __construct( + FilterFactory $filterFactory, + PluginFactory $pluginFactory, + ValidationFactory $validationFactory, + TcaDatabaseRecord $formDataGroup + ) { + + $this->filterFactory = $filterFactory; + $this->pluginFactory = $pluginFactory; + $this->validationFactory = $validationFactory; + $this->formDataGroup = $formDataGroup; + } + /** * Build the filter configuration from TCA * @@ -50,7 +84,7 @@ public function buildFilterFromTca(string $table, int $pageId) : array } // Filter:Types: string, integer, double, date, time, datetime and boolean. // Filter:Required: id, type, values* - $filter = GeneralUtility::makeInstance(FilterFactory::class) + $filter = $this->filterFactory ->create([ 'id' => $filterField, 'type' => $this->determineFilterType($fieldConfig), @@ -196,7 +230,7 @@ protected function determineAndAddExtras(Filter $filter): void default: } $filter->setPlugin( - GeneralUtility::makeInstance(PluginFactory::class) + $this->pluginFactory ->create([ 'identifier' => 'datetimepicker', 'configuration' => $pluginConfiguration, @@ -205,7 +239,7 @@ protected function determineAndAddExtras(Filter $filter): void if (!empty($pluginConfiguration['format'])) { $filter->setValidation( - GeneralUtility::makeInstance(ValidationFactory::class) + $this->validationFactory ->create([ 'format' => $pluginConfiguration['format'], ]) @@ -221,8 +255,8 @@ protected function determineAndAddExtras(Filter $filter): void */ protected function prepareTca(string $tableName, int $pageId) : array { - $formDataGroup = GeneralUtility::makeInstance(TcaDatabaseRecord::class); - $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup); +// TODO: check how to DI this? + $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $this->formDataGroup); $formDataCompilerInput = [ 'tableName' => $tableName, diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml new file mode 100644 index 0000000..e883fc8 --- /dev/null +++ b/Configuration/Services.yaml @@ -0,0 +1,32 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + T3G\Querybuilder\: + resource: '../Classes/*' + + T3G\Querybuilder\Backend\Form\FormDataGroup\TcaOnly: + public: true + + T3G\Querybuilder\Hooks\PageRenderer: + public: true; + arguments: + $pageRenderer: '@TYPO3\CMS\Core\Page\PageRenderer' + + + T3G\Querybuilder\Controller\QuerybuilderController: + # public: true; + arguments: + $connectionPool: '@TYPO3\CMS\Core\Context\Context' + $context: '@TYPO3\CMS\Core\Database\ConnectionPool' + + + T3G\Querybuilder\QueryBuilder: + # public: true; + arguments: + $filterFactory: '@T3G\Querybuilder\Factory\FilterFactory' + $pluginFactory: '@T3G\Querybuilder\Factory\PluginFactory' + $validationFactory: '@T3G\Querybuilder\Factory\ValidationFactory' + $formDataGroup: '@TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord' \ No newline at end of file From 8bd1524dac0c01418ca84e56766576f00291b12d Mon Sep 17 00:00:00 2001 From: Henrik Elsner Date: Sat, 16 Jan 2021 20:55:14 +0100 Subject: [PATCH 6/9] [TASK] Add further class to DI, cleanup Services.yaml, run php-cs-fixer --- Classes/Hooks/PageRenderer.php | 7 +++---- Classes/QueryBuilder.php | 1 - Configuration/Services.yaml | 19 ++----------------- 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/Classes/Hooks/PageRenderer.php b/Classes/Hooks/PageRenderer.php index adbafef..92ef00c 100644 --- a/Classes/Hooks/PageRenderer.php +++ b/Classes/Hooks/PageRenderer.php @@ -28,9 +28,10 @@ class PageRenderer */ protected $pageRenderer; - public function __construct(PageRenderer $pageRenderer) + public function __construct(\TYPO3\CMS\Core\Page\PageRenderer $pageRenderer, QueryBuilder $queryBuilder) { $this->pageRenderer = $pageRenderer; + $this->queryBuilder = $queryBuilder; } /** @@ -66,10 +67,8 @@ public function renderPreProcess(array $params): void $query = json_decode($queryParams['query'] ?? ''); $this->pageRenderer->addJsInlineCode('tx_querybuilder_query', 'var tx_querybuilder_query = ' . json_encode($query) . ';'); - $queryBuilder = GeneralUtility::makeInstance(QueryBuilder::class); - $pageId = (int)$queryParams['id']; - $filter = $queryBuilder->buildFilterFromTca($table, $pageId); + $filter = $this->queryBuilder->buildFilterFromTca($table, $pageId); $this->pageRenderer->addJsInlineCode('tx_querybuilder_filter', 'var tx_querybuilder_filter = ' . json_encode($filter) . ';'); $this->pageRenderer->loadRequireJsModule($languageModule); diff --git a/Classes/QueryBuilder.php b/Classes/QueryBuilder.php index 751fe97..d4e1f48 100644 --- a/Classes/QueryBuilder.php +++ b/Classes/QueryBuilder.php @@ -55,7 +55,6 @@ public function __construct( ValidationFactory $validationFactory, TcaDatabaseRecord $formDataGroup ) { - $this->filterFactory = $filterFactory; $this->pluginFactory = $pluginFactory; $this->validationFactory = $validationFactory; diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index e883fc8..d941c08 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -7,26 +7,11 @@ services: T3G\Querybuilder\: resource: '../Classes/*' - T3G\Querybuilder\Backend\Form\FormDataGroup\TcaOnly: - public: true - T3G\Querybuilder\Hooks\PageRenderer: public: true; - arguments: - $pageRenderer: '@TYPO3\CMS\Core\Page\PageRenderer' - T3G\Querybuilder\Controller\QuerybuilderController: - # public: true; - arguments: - $connectionPool: '@TYPO3\CMS\Core\Context\Context' - $context: '@TYPO3\CMS\Core\Database\ConnectionPool' - + public: true; T3G\Querybuilder\QueryBuilder: - # public: true; - arguments: - $filterFactory: '@T3G\Querybuilder\Factory\FilterFactory' - $pluginFactory: '@T3G\Querybuilder\Factory\PluginFactory' - $validationFactory: '@T3G\Querybuilder\Factory\ValidationFactory' - $formDataGroup: '@TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord' \ No newline at end of file + public: true; \ No newline at end of file From ed8d8a052f2ff845d449b60e901b4f3a9fca76fc Mon Sep 17 00:00:00 2001 From: Henrik Elsner Date: Tue, 19 Jan 2021 19:32:59 +0100 Subject: [PATCH 7/9] fix: remove bootstrap plugin definition, prevent call on undefined --- Resources/Public/JavaScript/QueryBuilder.js | 32 +++++++++------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/Resources/Public/JavaScript/QueryBuilder.js b/Resources/Public/JavaScript/QueryBuilder.js index bf34c64..cef206a 100644 --- a/Resources/Public/JavaScript/QueryBuilder.js +++ b/Resources/Public/JavaScript/QueryBuilder.js @@ -21,7 +21,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Storage/Client', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Notification', - 'twbs/bootstrap-datetimepicker', + 'TYPO3/CMS/Backend/DateTimePicker', 'query-builder' ], function ($, moment, Severity, ClientStorage, Modal, Notification) { 'use strict'; @@ -47,12 +47,6 @@ define(['jquery', table: $('table[data-table]').data('table'), querySelector: null, instance: null, - plugins: { - 'bt-tooltip-errors': {delay: 100}, - //'sortable': { icon: 'fa fa-sort' }, - 'invert': {}, - 'filter-description': {icon: 'fa fa-info'} - }, icon: 'fa fa-sort', // Filter:Types: string, integer, double, date, time, datetime and boolean. // Filter:Required: id, type, values* @@ -195,18 +189,20 @@ define(['jquery', table: QueryBuilder.table }, success: function(data) { - for (var j = 0; j < data.length; j++) { - var $query = $('