From 5fa1bef6d86ca9b3555d522f1b0ad91a624a7a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6rner?= Date: Fri, 20 Oct 2023 20:56:24 +0200 Subject: [PATCH] refactore DatabaseUtil::createWhereForSerializedBlob() --- src/EntityFinder/EntityFinderHelper.php | 6 +- src/Util/Database/DatabaseUtil.php | 55 ------------------ .../CreateWhereForSerializedBlobResult.php | 57 +++++++++++++++++++ src/Util/DatabaseUtil/DatabaseUtil.php | 17 ++++++ src/Util/User/UserUtil.php | 7 ++- src/Util/Utils.php | 2 +- tests/EntityFinder/EntityFinderHelperTest.php | 7 ++- tests/Util/DatabaseUtil/DatabaseUtilTest.php | 29 ++++++++++ tests/Util/User/UserUtilTest.php | 5 +- tests/Util/UtilsTest.php | 2 +- 10 files changed, 120 insertions(+), 67 deletions(-) delete mode 100644 src/Util/Database/DatabaseUtil.php create mode 100644 src/Util/DatabaseUtil/CreateWhereForSerializedBlobResult.php create mode 100644 src/Util/DatabaseUtil/DatabaseUtil.php create mode 100644 tests/Util/DatabaseUtil/DatabaseUtilTest.php diff --git a/src/EntityFinder/EntityFinderHelper.php b/src/EntityFinder/EntityFinderHelper.php index 9c7bc22e..cab3b6a1 100644 --- a/src/EntityFinder/EntityFinderHelper.php +++ b/src/EntityFinder/EntityFinderHelper.php @@ -33,10 +33,10 @@ public function __construct( */ public function findModulesByTypeAndSerializedValue(string $type, string $field, array $values): ?Collection { - ['columns' => $columns, 'values' => $values] = $this->utils->database() - ->createWhereForSerializedBlob(ModuleModel::getTable().'.'.$field, $values); + $blobQuery = $this->utils->database()->createWhereForSerializedBlob(ModuleModel::getTable().'.'.$field, $values); + $columns = [$blobQuery->createOrWhere()]; + $values = $blobQuery->values; - $columns = [$columns]; $columns[] = ModuleModel::getTable().'.type=?'; $values[] = $type; diff --git a/src/Util/Database/DatabaseUtil.php b/src/Util/Database/DatabaseUtil.php deleted file mode 100644 index 94da3c1f..00000000 --- a/src/Util/Database/DatabaseUtil.php +++ /dev/null @@ -1,55 +0,0 @@ - false, - 'inline_values' => false, - ], $options); - - $returnValues = []; - $connective = $options['condition_and'] ? 'AND' : 'OR'; - - $where = ''; - - foreach ($values as $val) { - if (!empty($where)) { - $where .= " $connective "; - } - - $value = ":\"$val\""; - - $where .= $options['condition_and'] ? '(' : ''; - - $where .= "$field REGEXP (".($options['inline_values'] ? $value : '?').')'; - - $where .= $options['condition_and'] ? ')' : ''; - - $returnValues[] = $value; - } - - return ['columns' => "($where)", 'values' => $returnValues]; - } -} \ No newline at end of file diff --git a/src/Util/DatabaseUtil/CreateWhereForSerializedBlobResult.php b/src/Util/DatabaseUtil/CreateWhereForSerializedBlobResult.php new file mode 100644 index 00000000..bd08a017 --- /dev/null +++ b/src/Util/DatabaseUtil/CreateWhereForSerializedBlobResult.php @@ -0,0 +1,57 @@ +field.' REGEXP ('.implode(") AND ".$this->field.' REGEXP (', $this->getValueList()).'))'; + } + + /** + * Return the where query with OR operation for each value. Values are inlined in the query ('REGEXP (':"3"')' instead of 'REGEXP (?)'). + */ + public function createInlineOrWhere(): string + { + return '('.$this->field.' REGEXP ('.implode(") OR ".$this->field.' REGEXP (', $this->getValueList()).'))'; + } + + /** + * Return the where query with AND operation and placeholder for each value ('REGEXP (?)'). Values can be obtained from the values property. + */ + public function createAndWhere(): string + { + + return '('.$this->field.' REGEXP ('.implode(") AND ".$this->field.' REGEXP (', array_fill(0, count($this->getValueList()), '?')).'))'; + } + + /** + * Return the where query with OR operation and placeholder for each value ('REGEXP (?)'). Values can be obtained from the values property. + */ + public function createOrWhere(): string + { + return '('.$this->field.' REGEXP ('.implode(") OR ".$this->field.' REGEXP (', array_fill(0, count($this->getValueList()), '?')).'))'; + } + + private function getValueList(): array + { + $returnValues = []; + + foreach ($this->values as $val) { + $returnValues[] = ":\"$val\""; + } + + return $returnValues; + } + +} \ No newline at end of file diff --git a/src/Util/DatabaseUtil/DatabaseUtil.php b/src/Util/DatabaseUtil/DatabaseUtil.php new file mode 100644 index 00000000..4c13317c --- /dev/null +++ b/src/Util/DatabaseUtil/DatabaseUtil.php @@ -0,0 +1,17 @@ +'".($time + 60)."') AND $table.disable=''"]; $columns[] = ''; - [$columns[], $tmpValues] = $this->databaseUtil->createWhereForSerializedBlob('groups', $groups); - $values = array_merge(array_values($values), array_values($tmpValues)); + $blobResult = $this->databaseUtil->createWhereForSerializedBlob('groups', $groups); + $columns[] = $blobResult->createOrWhere(); + $values = array_merge(array_values($values), array_values($blobResult->values)); return $adapter->findBy($columns, $values, $options); } diff --git a/src/Util/Utils.php b/src/Util/Utils.php index 3253afe2..8b184526 100644 --- a/src/Util/Utils.php +++ b/src/Util/Utils.php @@ -10,7 +10,7 @@ use HeimrichHannot\UtilsBundle\Util\Container\ContainerUtil; use HeimrichHannot\UtilsBundle\Util\Data\AnonymizeUtil; -use HeimrichHannot\UtilsBundle\Util\Database\DatabaseUtil; +use HeimrichHannot\UtilsBundle\Util\DatabaseUtil\DatabaseUtil; use HeimrichHannot\UtilsBundle\Util\Dca\DcaUtil; use HeimrichHannot\UtilsBundle\Util\File\FileUtil; use HeimrichHannot\UtilsBundle\Util\Html\HtmlUtil; diff --git a/tests/EntityFinder/EntityFinderHelperTest.php b/tests/EntityFinder/EntityFinderHelperTest.php index 9077735d..c4efc2ab 100644 --- a/tests/EntityFinder/EntityFinderHelperTest.php +++ b/tests/EntityFinder/EntityFinderHelperTest.php @@ -5,7 +5,8 @@ use Contao\ModuleModel; use Contao\TestCase\ContaoTestCase; use HeimrichHannot\UtilsBundle\EntityFinder\EntityFinderHelper; -use HeimrichHannot\UtilsBundle\Util\Database\DatabaseUtil; +use HeimrichHannot\UtilsBundle\Util\DatabaseUtil\CreateWhereForSerializedBlobResult; +use HeimrichHannot\UtilsBundle\Util\DatabaseUtil\DatabaseUtil; use HeimrichHannot\UtilsBundle\Util\Utils; class EntityFinderHelperTest extends ContaoTestCase @@ -19,7 +20,9 @@ public function testFindModulesByTypeAndSerializedValue() ]); $databaseUtilMock = $this->createMock(DatabaseUtil::class); - $databaseUtilMock->method('createWhereForSerializedBlob')->willReturn(['columns' => '', 'values' => []]); + $databaseUtilMock->method('createWhereForSerializedBlob')->willReturn( + new CreateWhereForSerializedBlobResult('field', []) + ); $utils = $this->createMock(Utils::class); $utils->method('database')->willReturn($databaseUtilMock); diff --git a/tests/Util/DatabaseUtil/DatabaseUtilTest.php b/tests/Util/DatabaseUtil/DatabaseUtilTest.php new file mode 100644 index 00000000..b8d9ace1 --- /dev/null +++ b/tests/Util/DatabaseUtil/DatabaseUtilTest.php @@ -0,0 +1,29 @@ +getTestInstance()->createWhereForSerializedBlob('elements', ['texts', 'headline']); + static::assertInstanceOf(CreateWhereForSerializedBlobResult::class, $result); + static::assertSame('(elements REGEXP (?) OR elements REGEXP (?))', $result->createOrWhere()); + static::assertSame('(elements REGEXP (?) AND elements REGEXP (?))', $result->createAndWhere()); + static::assertSame('(elements REGEXP (:"texts") OR elements REGEXP (:"headline"))', $result->createInlineOrWhere()); + static::assertSame('(elements REGEXP (:"texts") AND elements REGEXP (:"headline"))', $result->createInlineAndWhere()); + static::assertCount(2, $result->values); + } + + +} diff --git a/tests/Util/User/UserUtilTest.php b/tests/Util/User/UserUtilTest.php index 5ffa3dbc..7c68beb5 100644 --- a/tests/Util/User/UserUtilTest.php +++ b/tests/Util/User/UserUtilTest.php @@ -15,7 +15,8 @@ use Contao\UserModel; use HeimrichHannot\TestUtilitiesBundle\Mock\ModelMockTrait; use HeimrichHannot\UtilsBundle\Tests\AbstractUtilsTestCase; -use HeimrichHannot\UtilsBundle\Util\Database\DatabaseUtil; +use HeimrichHannot\UtilsBundle\Util\DatabaseUtil\CreateWhereForSerializedBlobResult; +use HeimrichHannot\UtilsBundle\Util\DatabaseUtil\DatabaseUtil; use HeimrichHannot\UtilsBundle\Util\Model\ModelUtil; use HeimrichHannot\UtilsBundle\Util\User\UserUtil; use PHPUnit\Framework\MockObject\MockBuilder; @@ -219,7 +220,7 @@ public function testFindActiveUsersByGroup() ]); $parameters['databaseUtil'] = $this->createMock(DatabaseUtil::class); $parameters['databaseUtil']->method('createWhereForSerializedBlob')->willReturnCallback(function (string $field, array $values) { - return [$field, $values]; + return new CreateWhereForSerializedBlobResult($field, $values); }); $instance = $this->getTestInstance($parameters); diff --git a/tests/Util/UtilsTest.php b/tests/Util/UtilsTest.php index 21be65cc..571523e8 100644 --- a/tests/Util/UtilsTest.php +++ b/tests/Util/UtilsTest.php @@ -11,7 +11,7 @@ use Contao\TestCase\ContaoTestCase; use HeimrichHannot\UtilsBundle\Util\Container\ContainerUtil; use HeimrichHannot\UtilsBundle\Util\Data\AnonymizeUtil; -use HeimrichHannot\UtilsBundle\Util\Database\DatabaseUtil; +use HeimrichHannot\UtilsBundle\Util\DatabaseUtil\DatabaseUtil; use HeimrichHannot\UtilsBundle\Util\Dca\DcaUtil; use HeimrichHannot\UtilsBundle\Util\Html\HtmlUtil; use HeimrichHannot\UtilsBundle\Util\Locale\LocaleUtil;