diff --git a/composer.json b/composer.json index 6f66ec2..8481fe0 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,7 @@ "require": { "php": ">=8.0", "ext-json": "*", + "ext-mbstring": "*", "ext-mysqli": "*", "activecollab/containeraccess": "^2.0", "activecollab/datevalue": "^2.0", @@ -27,6 +28,20 @@ "phpunit/phpunit": "~9.0", "pimple/pimple": "~3.5.0" }, + "replace": { + "symfony/polyfill-php54": "*", + "symfony/polyfill-php55": "*", + "symfony/polyfill-php56": "*", + "symfony/polyfill-php70": "*", + "symfony/polyfill-php71": "*", + "symfony/polyfill-php72": "*", + "symfony/polyfill-php73": "*", + "symfony/polyfill-php80": "*", + "symfony/polyfill-php81": "*", + "symfony/polyfill-mbstring": "*", + "symfony/polyfill-ctype": "*", + "symfony/polyfill-util": "*" + }, "autoload": { "psr-4": { "ActiveCollab\\DatabaseConnection\\": "src", diff --git a/composer.lock b/composer.lock index 28a867d..d00ed17 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "65dffb195d0ba868a019b653c1176f4e", + "content-hash": "3151f69d910267d555085ff5a589324b", "packages": [ { "name": "activecollab/containeraccess", @@ -304,184 +304,18 @@ }, "time": "2021-05-03T11:20:27+00:00" }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-11-30T18:21:41+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-09-13T13:58:33+00:00" - }, { "name": "symfony/translation", - "version": "v6.0.5", + "version": "v6.0.7", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "e69501c71107cc3146b32aaa45f4edd0c3427875" + "reference": "b2792b39d74cf41ea3065f27fd2ddf0b556ac7a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/e69501c71107cc3146b32aaa45f4edd0c3427875", - "reference": "e69501c71107cc3146b32aaa45f4edd0c3427875", + "url": "https://api.github.com/repos/symfony/translation/zipball/b2792b39d74cf41ea3065f27fd2ddf0b556ac7a1", + "reference": "b2792b39d74cf41ea3065f27fd2ddf0b556ac7a1", "shasum": "" }, "require": { @@ -547,7 +381,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.0.5" + "source": "https://github.com/symfony/translation/tree/v6.0.7" }, "funding": [ { @@ -563,20 +397,20 @@ "type": "tidelift" } ], - "time": "2022-02-09T15:52:48+00:00" + "time": "2022-03-31T17:18:25+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77" + "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/1b6ea5a7442af5a12dba3dbd6d71034b5b234e77", - "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9", + "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9", "shasum": "" }, "require": { @@ -625,7 +459,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.0.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.0.1" }, "funding": [ { @@ -641,7 +475,7 @@ "type": "tidelift" } ], - "time": "2021-09-07T12:43:40+00:00" + "time": "2022-01-02T09:55:41+00:00" } ], "packages-dev": [ @@ -718,16 +552,16 @@ }, { "name": "composer/semver", - "version": "3.2.9", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649" + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/a951f614bd64dcd26137bc9b7b2637ddcfc57649", - "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", "shasum": "" }, "require": { @@ -779,7 +613,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.2.9" + "source": "https://github.com/composer/semver/tree/3.3.2" }, "funding": [ { @@ -795,7 +629,7 @@ "type": "tidelift" } ], - "time": "2022-02-04T13:58:43+00:00" + "time": "2022-04-01T19:23:25+00:00" }, { "name": "composer/xdebug-handler", @@ -937,29 +771,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", + "doctrine/coding-standard": "^9", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" }, "type": "library", "autoload": { @@ -986,7 +821,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" }, "funding": [ { @@ -1002,7 +837,7 @@ "type": "tidelift" } ], - "time": "2020-11-10T18:47:58+00:00" + "time": "2022-03-03T08:28:38+00:00" }, { "name": "doctrine/lexer", @@ -1191,16 +1026,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.10.3", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "c6a951b75d684fd43fbbd69617488e1e2e8924ba" + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/c6a951b75d684fd43fbbd69617488e1e2e8924ba", - "reference": "c6a951b75d684fd43fbbd69617488e1e2e8924ba", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", "shasum": "" }, "require": { @@ -1238,7 +1073,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.10.3" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" }, "funding": [ { @@ -1246,7 +1081,7 @@ "type": "tidelift" } ], - "time": "2022-03-02T14:16:47+00:00" + "time": "2022-03-03T13:19:32+00:00" }, { "name": "nikic/php-parser", @@ -1582,16 +1417,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.0", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" + "reference": "77a32518733312af16a44300404e945338981de3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", "shasum": "" }, "require": { @@ -1626,9 +1461,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" }, - "time": "2022-01-04T19:58:01+00:00" + "time": "2022-03-15T21:29:03+00:00" }, { "name": "phpspec/prophecy", @@ -1699,16 +1534,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.14", + "version": "9.2.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "9f4d60b6afe5546421462b76cd4e633ebc364ab4" + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f4d60b6afe5546421462b76cd4e633ebc364ab4", - "reference": "9f4d60b6afe5546421462b76cd4e633ebc364ab4", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", "shasum": "" }, "require": { @@ -1764,7 +1599,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.14" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" }, "funding": [ { @@ -1772,7 +1607,7 @@ "type": "github" } ], - "time": "2022-02-28T12:38:02+00:00" + "time": "2022-03-07T09:28:20+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2017,16 +1852,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.16", + "version": "9.5.20", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "5ff8c545a50226c569310a35f4fa89d79f1ddfdc" + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5ff8c545a50226c569310a35f4fa89d79f1ddfdc", - "reference": "5ff8c545a50226c569310a35f4fa89d79f1ddfdc", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", "shasum": "" }, "require": { @@ -2056,7 +1891,7 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^2.3.4", + "sebastian/type": "^3.0", "sebastian/version": "^3.0.2" }, "require-dev": { @@ -2104,7 +1939,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.16" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" }, "funding": [ { @@ -2116,7 +1951,7 @@ "type": "github" } ], - "time": "2022-02-23T17:10:58+00:00" + "time": "2022-04-01T12:37:26+00:00" }, { "name": "pimple/pimple", @@ -2636,16 +2471,16 @@ }, { "name": "sebastian/environment", - "version": "5.1.3", + "version": "5.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac" + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", "shasum": "" }, "require": { @@ -2687,7 +2522,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" }, "funding": [ { @@ -2695,7 +2530,7 @@ "type": "github" } ], - "time": "2020-09-28T05:52:38+00:00" + "time": "2022-04-03T09:37:03+00:00" }, { "name": "sebastian/exporter", @@ -3127,28 +2962,28 @@ }, { "name": "sebastian/type", - "version": "2.3.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -3171,7 +3006,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" }, "funding": [ { @@ -3179,7 +3014,7 @@ "type": "github" } ], - "time": "2021-06-15T12:49:02+00:00" + "time": "2022-03-15T09:54:48+00:00" }, { "name": "sebastian/version", @@ -3236,16 +3071,16 @@ }, { "name": "symfony/console", - "version": "v5.4.5", + "version": "v5.4.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d8111acc99876953f52fe16d4c50eb60940d49ad" + "reference": "900275254f0a1a2afff1ab0e11abd5587a10e1d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d8111acc99876953f52fe16d4c50eb60940d49ad", - "reference": "d8111acc99876953f52fe16d4c50eb60940d49ad", + "url": "https://api.github.com/repos/symfony/console/zipball/900275254f0a1a2afff1ab0e11abd5587a10e1d6", + "reference": "900275254f0a1a2afff1ab0e11abd5587a10e1d6", "shasum": "" }, "require": { @@ -3315,7 +3150,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.5" + "source": "https://github.com/symfony/console/tree/v5.4.7" }, "funding": [ { @@ -3331,20 +3166,20 @@ "type": "tidelift" } ], - "time": "2022-02-24T12:45:35+00:00" + "time": "2022-03-31T17:09:19+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced" + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", - "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", "shasum": "" }, "require": { @@ -3382,7 +3217,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1" }, "funding": [ { @@ -3398,7 +3233,7 @@ "type": "tidelift" } ], - "time": "2021-11-01T23:48:49+00:00" + "time": "2022-01-02T09:55:41+00:00" }, { "name": "symfony/event-dispatcher", @@ -3487,16 +3322,16 @@ }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "aa5422287b75594b90ee9cd807caf8f0df491385" + "reference": "7bc61cc2db649b4637d331240c5346dcc7708051" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/aa5422287b75594b90ee9cd807caf8f0df491385", - "reference": "aa5422287b75594b90ee9cd807caf8f0df491385", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7bc61cc2db649b4637d331240c5346dcc7708051", + "reference": "7bc61cc2db649b4637d331240c5346dcc7708051", "shasum": "" }, "require": { @@ -3546,7 +3381,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.1" }, "funding": [ { @@ -3562,20 +3397,20 @@ "type": "tidelift" } ], - "time": "2021-07-15T12:33:35+00:00" + "time": "2022-01-02T09:55:41+00:00" }, { "name": "symfony/filesystem", - "version": "v5.4.5", + "version": "v5.4.7", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "797680071ea8f71b94eb958680c50d0e002638f5" + "reference": "3a4442138d80c9f7b600fb297534ac718b61d37f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/797680071ea8f71b94eb958680c50d0e002638f5", - "reference": "797680071ea8f71b94eb958680c50d0e002638f5", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/3a4442138d80c9f7b600fb297534ac718b61d37f", + "reference": "3a4442138d80c9f7b600fb297534ac718b61d37f", "shasum": "" }, "require": { @@ -3610,7 +3445,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.5" + "source": "https://github.com/symfony/filesystem/tree/v5.4.7" }, "funding": [ { @@ -3626,7 +3461,7 @@ "type": "tidelift" } ], - "time": "2022-02-27T10:31:47+00:00" + "time": "2022-04-01T12:33:59+00:00" }, { "name": "symfony/finder", @@ -3760,91 +3595,9 @@ ], "time": "2022-01-02T09:53:40+00:00" }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-10-20T20:35:02+00:00" - }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.24.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", @@ -3905,7 +3658,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0" }, "funding": [ { @@ -3925,7 +3678,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.24.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -3989,7 +3742,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0" }, "funding": [ { @@ -4007,241 +3760,18 @@ ], "time": "2021-02-19T12:13:01+00:00" }, - { - "name": "symfony/polyfill-php70", - "version": "v1.20.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", - "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "metapackage", - "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php70/tree/v1.20.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-23T14:02:19+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-05-27T09:17:38+00:00" - }, - { - "name": "symfony/polyfill-php73", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-06-05T21:20:04+00:00" - }, { "name": "symfony/process", - "version": "v5.4.5", + "version": "v5.4.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "95440409896f90a5f85db07a32b517ecec17fa4c" + "reference": "38a44b2517b470a436e1c944bf9b9ba3961137fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/95440409896f90a5f85db07a32b517ecec17fa4c", - "reference": "95440409896f90a5f85db07a32b517ecec17fa4c", + "url": "https://api.github.com/repos/symfony/process/zipball/38a44b2517b470a436e1c944bf9b9ba3961137fb", + "reference": "38a44b2517b470a436e1c944bf9b9ba3961137fb", "shasum": "" }, "require": { @@ -4274,7 +3804,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.5" + "source": "https://github.com/symfony/process/tree/v5.4.7" }, "funding": [ { @@ -4290,25 +3820,26 @@ "type": "tidelift" } ], - "time": "2022-01-30T18:16:22+00:00" + "time": "2022-03-18T16:18:52+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.4.1", + "version": "v2.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "d664541b99d6fb0247ec5ff32e87238582236204" + "reference": "24d9dc654b83e91aa59f9d167b131bc3b5bea24c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d664541b99d6fb0247ec5ff32e87238582236204", - "reference": "d664541b99d6fb0247ec5ff32e87238582236204", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/24d9dc654b83e91aa59f9d167b131bc3b5bea24c", + "reference": "24d9dc654b83e91aa59f9d167b131bc3b5bea24c", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.1" + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -4319,7 +3850,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -4356,7 +3887,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.4.1" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.1" }, "funding": [ { @@ -4372,7 +3903,7 @@ "type": "tidelift" } ], - "time": "2021-11-04T16:37:19+00:00" + "time": "2022-03-13T20:07:29+00:00" }, { "name": "symfony/stopwatch", diff --git a/src/BatchInsert/BatchInsert.php b/src/BatchInsert/BatchInsert.php index d94ba47..22f6c0e 100644 --- a/src/BatchInsert/BatchInsert.php +++ b/src/BatchInsert/BatchInsert.php @@ -9,6 +9,8 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\BatchInsert; use ActiveCollab\DatabaseConnection\ConnectionInterface; @@ -16,9 +18,6 @@ use InvalidArgumentException; use RuntimeException; -/** - * @package ActiveCollab\DatabaseConnection\BatchInsert - */ class BatchInsert implements BatchInsertInterface { /** diff --git a/src/BatchInsert/BatchInsertInterface.php b/src/BatchInsert/BatchInsertInterface.php index a9724ec..630b191 100644 --- a/src/BatchInsert/BatchInsertInterface.php +++ b/src/BatchInsert/BatchInsertInterface.php @@ -9,11 +9,10 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\BatchInsert; -/** - * @package ActiveCollab\DatabaseConnection\BatchInsert - */ interface BatchInsertInterface { /** diff --git a/src/Connection.php b/src/Connection.php index e34dee5..486a607 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -9,12 +9,13 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection; use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; /** - * @package ActiveCollab\DatabaseConnection * @deprecated */ class Connection extends MysqliConnection diff --git a/src/Connection/MysqliConnection.php b/src/Connection/MysqliConnection.php index 8f5c541..f755b97 100644 --- a/src/Connection/MysqliConnection.php +++ b/src/Connection/MysqliConnection.php @@ -9,6 +9,8 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Connection; use ActiveCollab\DatabaseConnection\BatchInsert\BatchInsert; @@ -20,6 +22,7 @@ use ActiveCollab\DatabaseConnection\Record\ValueCasterInterface; use ActiveCollab\DatabaseConnection\Result\Result; use ActiveCollab\DatabaseConnection\Result\ResultInterface; +use ActiveCollab\DatabaseConnection\Spatial\GeometricObjectInterface; use ActiveCollab\DateValue\DateValue; use DateTime; use Exception; @@ -702,11 +705,11 @@ private function prepareAndExecuteQuery($sql, $arguments) } return $result; - } else { - return empty($arguments) ? - $this->link->query($sql) : - $this->link->query(call_user_func_array([&$this, 'prepare'], array_merge([$sql], $arguments))); } + + return empty($arguments) ? + $this->link->query($sql) : + $this->link->query(call_user_func_array([&$this, 'prepare'], array_merge([$sql], $arguments))); } public function prepare($sql, ...$arguments) @@ -813,69 +816,74 @@ public function escapeValue($unescaped) // Date value if ($unescaped instanceof DateValue) { return "'" . $this->link->real_escape_string($unescaped->format('Y-m-d')) . "'"; + } // Date time value (including DateTimeValue) - } elseif ($unescaped instanceof DateTime) { + if ($unescaped instanceof DateTime) { return "'" . $this->link->real_escape_string($unescaped->format('Y-m-d H:i:s')) . "'"; + } - // Float - } else { - if (is_float($unescaped)) { - return "'" . str_replace(',', '.', (float) $unescaped) . "'"; // replace , with . for locales where comma is used by the system (German for example) + // Spatial data instances. + if ($unescaped instanceof GeometricObjectInterface) { + return sprintf("ST_GEOMFROMTEXT('%s')", $this->link->real_escape_string($unescaped->toWkt())); + } - // Boolean (maps to TINYINT(1)) - } else { - if (is_bool($unescaped)) { - return $unescaped ? "'1'" : "'0'"; + // Float + if (is_float($unescaped)) { + return sprintf( + "'%s'", + str_replace(',', '.', (string) (float) $unescaped) // replace , with . for locales where comma is used by the system (German for example) + ); + } - // NULL - } else { - if ($unescaped === null) { - return 'NULL'; - - // Escape first cell of each row - } else { - if ($unescaped instanceof ResultInterface) { - if ($unescaped->count() < 1) { - throw new InvalidArgumentException("Empty results can't be escaped"); - } + // Boolean (maps to TINYINT(1)) + if (is_bool($unescaped)) { + return $unescaped ? "'1'" : "'0'"; + } - $escaped = []; + // NULL + if ($unescaped === null) { + return 'NULL'; + } - foreach ($unescaped as $v) { - $escaped[] = $this->escapeValue(array_shift($v)); - } + // Escape first cell of each row + if ($unescaped instanceof ResultInterface) { + if ($unescaped->count() < 1) { + throw new InvalidArgumentException("Empty results can't be escaped"); + } - return '(' . implode(',', $escaped) . ')'; + $escaped = []; - // Escape each array element - } else { - if (is_array($unescaped)) { - if (empty($unescaped)) { - throw new InvalidArgumentException("Empty arrays can't be escaped"); - } + foreach ($unescaped as $v) { + $escaped[] = $this->escapeValue(array_shift($v)); + } - $escaped = []; + return '(' . implode(',', $escaped) . ')'; + } - foreach ($unescaped as $v) { - $escaped[] = $this->escapeValue($v); - } + // Escape each array element + if (is_array($unescaped)) { + if (empty($unescaped)) { + throw new InvalidArgumentException("Empty arrays can't be escaped"); + } - return '(' . implode(',', $escaped) . ')'; + $escaped = []; - // Regular string and integer escape - } else { - if (is_scalar($unescaped)) { - return "'" . $this->link->real_escape_string($unescaped) . "'"; - } else { - throw new InvalidArgumentException('Value is expected to be scalar, array, or instance of: DateTime or Result'); - } - } - } - } - } + foreach ($unescaped as $v) { + $escaped[] = $this->escapeValue($v); } + + return '(' . implode(',', $escaped) . ')'; } + + // Regular string and integer escape + if (is_scalar($unescaped)) { + return sprintf("'%s'", $this->link->real_escape_string((string) $unescaped)); + } + + throw new InvalidArgumentException( + 'Value is expected to be scalar, array, or instance of: DateTime or Result' + ); } public function escapeFieldName($unescaped) diff --git a/src/ConnectionFactory.php b/src/ConnectionFactory.php index 4162d3b..56b178c 100644 --- a/src/ConnectionFactory.php +++ b/src/ConnectionFactory.php @@ -9,18 +9,16 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection; use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; use ActiveCollab\DatabaseConnection\Exception\ConnectionException; use Exception; use mysqli as MysqliLink; -use mysqli_sql_exception; use Psr\Log\LoggerInterface; -/** - * @package ActiveCollab\DatabaseConnection - */ class ConnectionFactory { public function __construct( @@ -30,13 +28,13 @@ public function __construct( } public function mysqli( - $host, - $user, - $pass, - $select_database = '', - $set_connection_encoding = null, - $set_connection_encoding_with_query = false - ) + string $host, + string $user, + string $pass, + string $select_database = '', + string $set_connection_encoding = null, + bool $set_connection_encoding_with_query = false + ): MysqliConnection { try { if (str_contains($host, ':')) { @@ -62,6 +60,21 @@ public function mysqli( $link->set_charset($set_connection_encoding); } + return $this->mysqliFromLink( + $link, + $select_database, + $set_connection_encoding, + $set_connection_encoding_with_query + ); + } + + public function mysqliFromLink( + MysqliLink $link, + string $select_database = '', + string $set_connection_encoding = null, + bool $set_connection_encoding_with_query = false + ): MysqliConnection + { $connection = new MysqliConnection($link, $this->log); if ($select_database) { @@ -75,16 +88,13 @@ public function mysqli( return $connection; } - /** - * @param string $host - * @param int $port - * @param string $user - * @param string $pass - * @param string $select_database - * @return MysqliLink - * @throws ConnectionException - */ - private function mysqliConnectFromParams($host, $port, $user, $pass, $select_database = '') + private function mysqliConnectFromParams( + string $host, + int $port, + string $user, + string $pass, + string $select_database = '' + ): MysqliLink { try { $link = new MysqliLink($host, $user, $pass, '', $port); diff --git a/src/ConnectionFactoryInterface.php b/src/ConnectionFactoryInterface.php index 351c1e3..5f349c0 100644 --- a/src/ConnectionFactoryInterface.php +++ b/src/ConnectionFactoryInterface.php @@ -9,25 +9,28 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection; use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; +use mysqli as MysqliLink; -/** - * @package ActiveCollab\DatabaseConnection - */ interface ConnectionFactoryInterface { - /** - * Connect to MySQL using mysqli extension. - * - * @param string $host - * @param string $user - * @param string $pass - * @param string $select_database - * @param string|null $set_connection_encoding - * @param bool $set_connection_encoding_with_query - * @return MysqliConnection - */ - public function mysqli($host, $user, $pass, $select_database = '', $set_connection_encoding = null, $set_connection_encoding_with_query = false); + public function mysqli( + string $host, + string $user, + string $pass, + string $select_database = '', + string $set_connection_encoding = null, + bool $set_connection_encoding_with_query = false + ): MysqliConnection; + + public function mysqliFromLink( + MysqliLink $link, + string $select_database = '', + string $set_connection_encoding = null, + bool $set_connection_encoding_with_query = false + ): MysqliConnection; } diff --git a/src/ConnectionInterface.php b/src/ConnectionInterface.php index 55a2caa..e719e8a 100644 --- a/src/ConnectionInterface.php +++ b/src/ConnectionInterface.php @@ -170,13 +170,12 @@ public function selectFirstColumn($table_name, $fields = null, $conditions = nul public function count(string $table_name, $conditions = null, $field = 'id'): int; /** - * Insert into $table a row that is reperesented with $values (key is field name, and value is value that we need to set). + * Insert into $table a row that is represented with $values (key is field name, and value is value that we need to set). * * @param string $table_name * @param array $field_value_map * @param string $mode * @return int - * @throws InvalidArgumentException */ public function insert( string $table_name, diff --git a/src/Exception/ExceptionInterface.php b/src/Exception/ExceptionInterface.php index c6c6e0d..1b7bf39 100644 --- a/src/Exception/ExceptionInterface.php +++ b/src/Exception/ExceptionInterface.php @@ -9,11 +9,10 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Exception; -/** - * @package ActiveCollab\DatabaseConnection\Exception - */ interface ExceptionInterface { } diff --git a/src/Exception/QueryException.php b/src/Exception/QueryException.php index 426d898..15e6a86 100644 --- a/src/Exception/QueryException.php +++ b/src/Exception/QueryException.php @@ -9,6 +9,8 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Exception; use Exception; diff --git a/src/Record/LoadFromRow.php b/src/Record/LoadFromRow.php index 67e5c6f..2b7478f 100644 --- a/src/Record/LoadFromRow.php +++ b/src/Record/LoadFromRow.php @@ -9,15 +9,11 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Record; -/** - * @package ActiveCollab\DatabaseConnection\Record - */ interface LoadFromRow { - /** - * @param array $row - */ public function loadFromRow(array $row); } diff --git a/src/Record/ValueCaster.php b/src/Record/ValueCaster.php index 1774a29..6c7c624 100644 --- a/src/Record/ValueCaster.php +++ b/src/Record/ValueCaster.php @@ -9,28 +9,25 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Record; +use ActiveCollab\DatabaseConnection\Spatial\WktParser\WktParser; use ActiveCollab\DateValue\DateTimeValue; use ActiveCollab\DateValue\DateValue; use RuntimeException; -/** - * @package ActiveCollab\DatabaseConnection\Record - */ class ValueCaster implements ValueCasterInterface { - /** - * @var array - */ - private $dictated = ['id' => self::CAST_INT, 'row_count' => self::CAST_INT]; + private array $dictated = [ + 'id' => self::CAST_INT, + 'row_count' => self::CAST_INT, + ]; - /** - * @param array|null $dictated - */ public function __construct(array $dictated = null) { - if ($dictated && is_array($dictated)) { + if ($dictated) { $this->dictated = array_merge($this->dictated, $dictated); } } @@ -66,8 +63,6 @@ public function castValue($field_name, $value) return (int) $value; case self::CAST_FLOAT: return (float) $value; - case self::CAST_STRING: - return (string) $value; case self::CAST_BOOL: return (bool) $value; case self::CAST_DATE: @@ -77,34 +72,35 @@ public function castValue($field_name, $value) case self::CAST_JSON: if (empty($value)) { return null; - } else { - $result = json_decode($value, true); + } - if (empty($result) && json_last_error()) { - throw new RuntimeException('Failed to parse JSON. Reason: ' . json_last_error_msg(), json_last_error()); - } + $result = json_decode($value, true); - return $result; + if (empty($result) && json_last_error()) { + throw new RuntimeException( + sprintf('Failed to parse JSON. Reason: %s', json_last_error_msg()), + json_last_error() + ); } - default: - return (string) $value; + + return $result; + case self::CAST_SPATIAL: + return (new WktParser())->geomFromText((string) $value); } + + return (string) $value; } - /** - * Return type by field name. - * - * @param string $field_name - * - * @return string - */ - public function getTypeByFieldName($field_name) + public function getTypeByFieldName(string $field_name): string { if (isset($this->dictated[$field_name])) { return $this->dictated[$field_name]; } - if (substr($field_name, 0, 3) === 'is_' || in_array(substr($field_name, 0, 4), ['has_', 'had_', 'was_']) || in_array(substr($field_name, 0, 5), ['were_', 'have_'])) { + if (str_starts_with($field_name, 'is_') + || in_array(substr($field_name, 0, 4), ['has_', 'had_', 'was_']) + || in_array(substr($field_name, 0, 5), ['were_', 'have_']) + ) { return self::CAST_BOOL; } diff --git a/src/Record/ValueCasterInterface.php b/src/Record/ValueCasterInterface.php index 69f2cc5..5763a81 100644 --- a/src/Record/ValueCasterInterface.php +++ b/src/Record/ValueCasterInterface.php @@ -9,11 +9,10 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Record; -/** - * @package ActiveCollab\DatabaseConnection\Record - */ interface ValueCasterInterface { const CAST_INT = 'int'; @@ -23,6 +22,7 @@ interface ValueCasterInterface const CAST_DATE = 'date'; const CAST_DATETIME = 'datetime'; const CAST_JSON = 'json'; + const CAST_SPATIAL = 'wkt'; /** * Cast row value to native PHP types based on caster settings. @@ -43,10 +43,6 @@ public function castValue($field_name, $value); /** * Return type by field name. - * - * @param string $field_name - * - * @return string */ - public function getTypeByFieldName($field_name); + public function getTypeByFieldName(string $field_name): string; } diff --git a/src/Result/Result.php b/src/Result/Result.php index 119f336..1f15c00 100644 --- a/src/Result/Result.php +++ b/src/Result/Result.php @@ -9,6 +9,8 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Result; use ActiveCollab\ContainerAccess\ContainerAccessInterface; diff --git a/src/Result/ResultInterface.php b/src/Result/ResultInterface.php index 53c85dd..4f62a8f 100644 --- a/src/Result/ResultInterface.php +++ b/src/Result/ResultInterface.php @@ -9,6 +9,8 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Result; use ActiveCollab\DatabaseConnection\Record\LoadFromRow; @@ -18,9 +20,6 @@ use IteratorAggregate; use JsonSerializable; -/** - * @package ActiveCollab\DatabaseConnection\Result - */ interface ResultInterface extends IteratorAggregate, ArrayAccess, Countable, JsonSerializable { /** diff --git a/src/Result/ResultIterator.php b/src/Result/ResultIterator.php index 39aadd7..a92a6f3 100644 --- a/src/Result/ResultIterator.php +++ b/src/Result/ResultIterator.php @@ -9,6 +9,8 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Result; use Iterator; diff --git a/src/Spatial/Coordinate/Coordinate.php b/src/Spatial/Coordinate/Coordinate.php new file mode 100644 index 0000000..584b1bf --- /dev/null +++ b/src/Spatial/Coordinate/Coordinate.php @@ -0,0 +1,26 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\Coordinate; + +class Coordinate implements CoordinateInterface +{ + private float $value; + + public function __construct(float $value) + { + $this->value = $value; + } + + public function getValue(): float + { + return $this->value; + } +} diff --git a/src/Spatial/Coordinate/CoordinateInterface.php b/src/Spatial/Coordinate/CoordinateInterface.php new file mode 100644 index 0000000..b73f151 --- /dev/null +++ b/src/Spatial/Coordinate/CoordinateInterface.php @@ -0,0 +1,16 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\Coordinate; + +interface CoordinateInterface +{ + public function getValue(): float; +} diff --git a/src/Spatial/GeometricObjectInterface.php b/src/Spatial/GeometricObjectInterface.php new file mode 100644 index 0000000..a22eb77 --- /dev/null +++ b/src/Spatial/GeometricObjectInterface.php @@ -0,0 +1,18 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial; + +use Stringable; + +interface GeometricObjectInterface extends Stringable +{ + public function toWkt(): string; +} diff --git a/src/Spatial/LineString/LineString.php b/src/Spatial/LineString/LineString.php new file mode 100644 index 0000000..3fdcc71 --- /dev/null +++ b/src/Spatial/LineString/LineString.php @@ -0,0 +1,56 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\LineString; + +use ActiveCollab\DatabaseConnection\Spatial\Point\PointInterface; +use LogicException; + +class LineString implements LineStringInterface +{ + /** + * @var PointInterface[] + */ + private array $points; + + public function __construct( + PointInterface ...$points + ) + { + if (count($points) < 2) { + throw new LogicException('At least two points are required.'); + } + + $this->points = $points; + } + + public function getPoints(): array + { + return $this->points; + } + + public function toWkt(): string + { + return sprintf('LINESTRING(%s)', $this); + } + + public function __toString(): string + { + return implode( + ',', + array_map( + function (PointInterface $coordinate) { + return (string) $coordinate; + }, + $this->points + ) + ); + } +} diff --git a/src/Spatial/LineString/LineStringInterface.php b/src/Spatial/LineString/LineStringInterface.php new file mode 100644 index 0000000..69afef3 --- /dev/null +++ b/src/Spatial/LineString/LineStringInterface.php @@ -0,0 +1,18 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\LineString; + +use ActiveCollab\DatabaseConnection\Spatial\GeometricObjectInterface; + +interface LineStringInterface extends GeometricObjectInterface +{ + public function getPoints(): array; +} diff --git a/src/Spatial/LinearRing/LinearRing.php b/src/Spatial/LinearRing/LinearRing.php new file mode 100644 index 0000000..d4ac736 --- /dev/null +++ b/src/Spatial/LinearRing/LinearRing.php @@ -0,0 +1,38 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\LinearRing; + +use ActiveCollab\DatabaseConnection\Spatial\LineString\LineString; +use ActiveCollab\DatabaseConnection\Spatial\Point\PointInterface; +use LogicException; + +class LinearRing extends LineString implements LinearRingInterface +{ + public function __construct( + PointInterface ...$points + ) + { + if (count($points) < 4) { + throw new LogicException('At least four points are required.'); + } + + if (!$points[0]->isSame($points[count($points) - 1])) { + throw new LogicException('Linear ring is not closed.'); + } + + parent::__construct(...$points); + } + + public function toWkt(): string + { + throw new LogicException('WKT is not available for line rings.'); + } +} diff --git a/src/Spatial/LinearRing/LinearRingInterface.php b/src/Spatial/LinearRing/LinearRingInterface.php new file mode 100644 index 0000000..85f29b9 --- /dev/null +++ b/src/Spatial/LinearRing/LinearRingInterface.php @@ -0,0 +1,22 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\LinearRing; + +use ActiveCollab\DatabaseConnection\Spatial\LineString\LineStringInterface; +use ActiveCollab\DatabaseConnection\Spatial\Point\PointInterface; + +interface LinearRingInterface extends LineStringInterface +{ + /** + * @return PointInterface[] + */ + public function getPoints(): array; +} diff --git a/src/Spatial/MultiLineString/MultiLineString.php b/src/Spatial/MultiLineString/MultiLineString.php new file mode 100644 index 0000000..83135bf --- /dev/null +++ b/src/Spatial/MultiLineString/MultiLineString.php @@ -0,0 +1,49 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\MultiLineString; + +use ActiveCollab\DatabaseConnection\Spatial\LineString\LineStringInterface; + +class MultiLineString implements MultiLineStringInterface +{ + /** + * @var LineStringInterface[] + */ + private array $lines; + + public function __construct(LineStringInterface ...$lines) + { + $this->lines = $lines; + } + + public function getLines(): array + { + return $this->lines; + } + + public function toWkt(): string + { + return sprintf('MULTILINESTRING(%s)', $this); + } + + public function __toString(): string + { + return implode( + ',', + array_map( + function (LineStringInterface $line_string) { + return sprintf('(%s)', $line_string); + }, + $this->getLines() + ) + ); + } +} diff --git a/src/Spatial/MultiLineString/MultiLineStringInterface.php b/src/Spatial/MultiLineString/MultiLineStringInterface.php new file mode 100644 index 0000000..3758400 --- /dev/null +++ b/src/Spatial/MultiLineString/MultiLineStringInterface.php @@ -0,0 +1,18 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\MultiLineString; + +use ActiveCollab\DatabaseConnection\Spatial\GeometricObjectInterface; + +interface MultiLineStringInterface extends GeometricObjectInterface +{ + public function getLines(): array; +} diff --git a/src/Spatial/MultiPoint/MultiPoint.php b/src/Spatial/MultiPoint/MultiPoint.php new file mode 100644 index 0000000..66383da --- /dev/null +++ b/src/Spatial/MultiPoint/MultiPoint.php @@ -0,0 +1,54 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\MultiPoint; + +use ActiveCollab\DatabaseConnection\Spatial\Point\PointInterface; +use LogicException; + +class MultiPoint implements MultiPointInterface +{ + /** + * @var PointInterface[] + */ + private array $points; + + public function __construct(PointInterface ...$points) + { + if (count($points) < 2) { + throw new LogicException('At least two points are required.'); + } + + $this->points = $points; + } + + public function getPoints(): array + { + return $this->points; + } + + public function toWkt(): string + { + return sprintf('MULTIPOINT(%s)', $this); + } + + public function __toString(): string + { + return implode( + ',', + array_map( + function (PointInterface $coordinate) { + return (string) $coordinate; + }, + $this->getPoints() + ) + ); + } +} diff --git a/src/Spatial/MultiPoint/MultiPointInterface.php b/src/Spatial/MultiPoint/MultiPointInterface.php new file mode 100644 index 0000000..cee04e5 --- /dev/null +++ b/src/Spatial/MultiPoint/MultiPointInterface.php @@ -0,0 +1,18 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\MultiPoint; + +use ActiveCollab\DatabaseConnection\Spatial\GeometricObjectInterface; + +interface MultiPointInterface extends GeometricObjectInterface +{ + public function getPoints(): array; +} diff --git a/src/Spatial/MultiPolygon/MultiPolygon.php b/src/Spatial/MultiPolygon/MultiPolygon.php new file mode 100644 index 0000000..81278cb --- /dev/null +++ b/src/Spatial/MultiPolygon/MultiPolygon.php @@ -0,0 +1,49 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\MultiPolygon; + +use ActiveCollab\DatabaseConnection\Spatial\Polygon\PolygonInterface; + +class MultiPolygon implements MultiPolygonInterface +{ + /** + * @var PolygonInterface[] + */ + private array $polygons; + + public function __construct(PolygonInterface ...$polygons) + { + $this->polygons = $polygons; + } + + public function getPolygons(): array + { + return $this->polygons; + } + + public function toWkt(): string + { + return sprintf('MULTIPOLYGON(%s)', $this); + } + + public function __toString(): string + { + return implode( + ',', + array_map( + function (PolygonInterface $polygon) { + return sprintf('(%s)', $polygon); + }, + $this->getPolygons() + ) + ); + } +} diff --git a/src/Spatial/MultiPolygon/MultiPolygonInterface.php b/src/Spatial/MultiPolygon/MultiPolygonInterface.php new file mode 100644 index 0000000..736e06f --- /dev/null +++ b/src/Spatial/MultiPolygon/MultiPolygonInterface.php @@ -0,0 +1,18 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\MultiPolygon; + +use ActiveCollab\DatabaseConnection\Spatial\GeometricObjectInterface; + +interface MultiPolygonInterface extends GeometricObjectInterface +{ + public function getPolygons(): array; +} diff --git a/src/Spatial/Point/Point.php b/src/Spatial/Point/Point.php new file mode 100644 index 0000000..ea19798 --- /dev/null +++ b/src/Spatial/Point/Point.php @@ -0,0 +1,66 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\Point; + +use ActiveCollab\DatabaseConnection\Spatial\Coordinate\CoordinateInterface; + +class Point implements PointInterface +{ + public function __construct( + private CoordinateInterface $x_coordinate, + private CoordinateInterface $y_coordinate, + ) + { + } + + public function getX(): CoordinateInterface + { + return $this->x_coordinate; + } + + public function getY(): CoordinateInterface + { + return $this->y_coordinate; + } + + public function isSame(PointInterface $coordinate): bool + { + return $coordinate->getX()->getValue() === $this->getX()->getValue() && + $coordinate->getY()->getValue() === $this->getY()->getValue(); + } + + public function toWkt(): string + { + return sprintf('POINT(%s)', $this); + } + + public function __toString(): string + { + return sprintf( + '%s %s', + $this->formatNumber($this->getX()->getValue()), + $this->formatNumber($this->getY()->getValue()), + ); + } + + private function formatNumber(float $number): string + { + return rtrim( + number_format( + $number, + 8, + '.', + '' + ), + '0' + ); + } +} diff --git a/src/Spatial/Point/PointInterface.php b/src/Spatial/Point/PointInterface.php new file mode 100644 index 0000000..db1230b --- /dev/null +++ b/src/Spatial/Point/PointInterface.php @@ -0,0 +1,21 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\Point; + +use ActiveCollab\DatabaseConnection\Spatial\Coordinate\CoordinateInterface; +use ActiveCollab\DatabaseConnection\Spatial\GeometricObjectInterface; + +interface PointInterface extends GeometricObjectInterface +{ + public function getX(): CoordinateInterface; + public function getY(): CoordinateInterface; + public function isSame(PointInterface $coordinate): bool; +} diff --git a/src/Spatial/Polygon/Polygon.php b/src/Spatial/Polygon/Polygon.php new file mode 100644 index 0000000..c9d74ed --- /dev/null +++ b/src/Spatial/Polygon/Polygon.php @@ -0,0 +1,57 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\Polygon; + +use ActiveCollab\DatabaseConnection\Spatial\LinearRing\LinearRingInterface; + +class Polygon implements PolygonInterface +{ + /** + * @var LinearRingInterface[] + */ + private array $inner_boundaries; + + public function __construct( + private LinearRingInterface $exterior_boundary, + LinearRingInterface ...$inner_boundaries + ) + { + $this->inner_boundaries = $inner_boundaries; + } + + public function getExteriorBoundary(): LinearRingInterface + { + return $this->exterior_boundary; + } + + public function getInnerBoundaries(): array + { + return $this->inner_boundaries; + } + + public function toWkt(): string + { + return sprintf('POLYGON(%s)', $this); + } + + public function __toString(): string + { + $boundaries = [ + sprintf('(%s)', $this->getExteriorBoundary()), + ]; + + foreach ($this->getInnerBoundaries() as $inner_boundary) { + $boundaries[] = sprintf('(%s)', $inner_boundary); + } + + return implode(', ', $boundaries); + } +} diff --git a/src/Spatial/Polygon/PolygonInterface.php b/src/Spatial/Polygon/PolygonInterface.php new file mode 100644 index 0000000..87539c5 --- /dev/null +++ b/src/Spatial/Polygon/PolygonInterface.php @@ -0,0 +1,20 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\Polygon; + +use ActiveCollab\DatabaseConnection\Spatial\LinearRing\LinearRingInterface; +use ActiveCollab\DatabaseConnection\Spatial\GeometricObjectInterface; + +interface PolygonInterface extends GeometricObjectInterface +{ + public function getExteriorBoundary(): LinearRingInterface; + public function getInnerBoundaries(): array; +} diff --git a/src/Spatial/WktParser/InvalidWktException.php b/src/Spatial/WktParser/InvalidWktException.php new file mode 100644 index 0000000..fc0164a --- /dev/null +++ b/src/Spatial/WktParser/InvalidWktException.php @@ -0,0 +1,28 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\WktParser; + +use Exception; +use Throwable; + +class InvalidWktException extends Exception +{ + public function __construct(string $text, Throwable $previous = null) { + parent::__construct( + sprintf( + "Invalid WKT: '%s'", + $text + ), + 0, + $previous + ); + } +} diff --git a/src/Spatial/WktParser/WktParser.php b/src/Spatial/WktParser/WktParser.php new file mode 100644 index 0000000..93e7512 --- /dev/null +++ b/src/Spatial/WktParser/WktParser.php @@ -0,0 +1,181 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Spatial\WktParser; + +use ActiveCollab\DatabaseConnection\Spatial\LineString\LineString; +use ActiveCollab\DatabaseConnection\Spatial\LineString\LineStringInterface; +use ActiveCollab\DatabaseConnection\Spatial\MultiLineString\MultiLineString; +use ActiveCollab\DatabaseConnection\Spatial\MultiLineString\MultiLineStringInterface; +use ActiveCollab\DatabaseConnection\Spatial\MultiPoint\MultiPoint; +use ActiveCollab\DatabaseConnection\Spatial\MultiPoint\MultiPointInterface; +use ActiveCollab\DatabaseConnection\Spatial\MultiPolygon\MultiPolygon; +use ActiveCollab\DatabaseConnection\Spatial\MultiPolygon\MultiPolygonInterface; +use ActiveCollab\DatabaseConnection\Spatial\Point\Point; +use ActiveCollab\DatabaseConnection\Spatial\Point\PointInterface; +use ActiveCollab\DatabaseConnection\Spatial\Coordinate\Coordinate; +use ActiveCollab\DatabaseConnection\Spatial\LinearRing\LinearRing; +use ActiveCollab\DatabaseConnection\Spatial\LinearRing\LinearRingInterface; +use ActiveCollab\DatabaseConnection\Spatial\Polygon\Polygon; +use ActiveCollab\DatabaseConnection\Spatial\Polygon\PolygonInterface; +use Exception; +use LogicException; + +class WktParser +{ + const POINT = 'Point'; + const MULTI_POINT = 'MultiPoint'; + const LINE_STRING = 'LineString'; + const MULTI_LINE_STRING = 'MultiLinestring'; + const LINEAR_RING = 'LinearRing'; + const POLYGON = 'Polygon'; + const MULTI_POLYGON = 'MultiPolygon'; + const GEOMETRY_COLLECTION = 'GeometryCollection'; + + private const WKT_TYPES = [ + self::POINT, + self::MULTI_POINT, + self::LINE_STRING, + self::MULTI_LINE_STRING, + self::LINEAR_RING, + self::POLYGON, + self::MULTI_POLYGON, + self::GEOMETRY_COLLECTION, + ]; + + public function geomFromText($text) { + $lowered_text = strtolower($text); + $type_pattern = '/\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/'; + if (!preg_match($type_pattern, $lowered_text, $matches)) { + throw new InvalidWktException($text); + } + foreach (self::WKT_TYPES as $wkt_type) { + if (strtolower($wkt_type) == $matches[1]) { + $type = $wkt_type; + break; + } + } + + if (!isset($type)) { + throw new InvalidWktException($text); + } + + try { + $components = call_user_func( + [ + $this, + sprintf('parse%s', $type), + ], + $matches[2] + ); + } catch (Exception $e) { + throw new InvalidWktException($text, $e); + } + + if (in_array($type, [self::POINT, self::MULTI_POINT, self::LINE_STRING, self::MULTI_LINE_STRING, self::POLYGON, self::MULTI_POLYGON])) { + return $components; + } + + throw new LogicException(sprintf('Unsupported type %s.', $type)); + } + + private function parsePoint(string $text): PointInterface + { + $parsed_text = preg_split('/\s+/', trim($text)); + + return new Point( + new Coordinate((float) $parsed_text[0]), + new Coordinate((float) $parsed_text[1]), + ); + } + + protected function parseMultiPoint(string $str): MultiPointInterface + { + $str = trim($str); + + if (empty($str)) { + return new MultiPoint(); + } + + return new MultiPoint(...$this->parseLineString($str)->getPoints()); + } + + protected function parseLineString(string $text): LineStringInterface + { + $points = []; + + foreach (preg_split('/,/', trim($text)) as $point_text) { + $points[] = $this->parsePoint($point_text); + } + + return new LineString(...$points); + } + + private function parseMultiLineString(string $text): MultiLineStringInterface + { + return new MultiLineString(...$this->parseCollection($text, self::LINE_STRING)); + } + + private function parseLinearRing(string $text): LinearRingInterface + { + return new LinearRing(...$this->parseLineString($text)->getPoints()); + } + + private function parsePolygon(string $text): PolygonInterface + { + $boundaries = $this->parseCollection($text, self::LINEAR_RING); + $exterior_boundary = array_pop($boundaries); + + return new Polygon($exterior_boundary, ...$boundaries); + } + + protected function parseMultiPolygon($str): MultiPolygonInterface + { + return new MultiPolygon(...$this->parseCollection($str, "Polygon")); + } + + protected function parseGeometryCollection($str) { + $components = []; + foreach (preg_split('/,\s*(?=[A-Za-z])/', trim($str)) as $compstr) { + $components[] = $this->geomFromText($compstr); + } + return $components; + } + + private function parseCollection( + string $text, + string $child_constructor + ): array + { + $components = []; + + foreach (preg_split('/\)\s*,\s*\(/', trim($text)) as $parse_text) { + if (strlen($parse_text) and $parse_text[0] == '(') { + $parse_text = substr($parse_text, 1); + } + + if (strlen($parse_text) and $parse_text[strlen($parse_text)-1] == ')') { + $parse_text = substr($parse_text, 0, -1); + } + + $components[] = call_user_func( + [ + $this, + sprintf('parse%s', $child_constructor) + ], + $parse_text + ); + } + + return $components; + } +} diff --git a/test/bootstrap.php b/test/bootstrap.php index 88bd9de..a9dcda5 100644 --- a/test/bootstrap.php +++ b/test/bootstrap.php @@ -12,4 +12,5 @@ date_default_timezone_set('GMT'); require dirname(__DIR__) . '/vendor/autoload.php'; -require __DIR__ . '/src/TestCase.php'; +require __DIR__ . '/src/Base/TestCase.php'; +require __DIR__ . '/src/Base/DbLinkedTestCase.php'; diff --git a/test/src/Base/DbConnectedTestCase.php b/test/src/Base/DbConnectedTestCase.php new file mode 100644 index 0000000..0763fae --- /dev/null +++ b/test/src/Base/DbConnectedTestCase.php @@ -0,0 +1,30 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Test\Base; + +use ActiveCollab\DatabaseConnection\ConnectionFactory; +use ActiveCollab\DatabaseConnection\ConnectionInterface; + +class DbConnectedTestCase extends DbLinkedTestCase +{ + protected ConnectionInterface $connection; + + public function setUp(): void + { + parent::setUp(); + + $this->connection = (new ConnectionFactory()) + ->mysqliFromLink($this->link); + } +} diff --git a/test/src/TestCase.php b/test/src/Base/DbLinkedTestCase.php similarity index 72% rename from test/src/TestCase.php rename to test/src/Base/DbLinkedTestCase.php index 8f5186d..319904d 100644 --- a/test/src/TestCase.php +++ b/test/src/Base/DbLinkedTestCase.php @@ -9,25 +9,17 @@ * with this source code in the file LICENSE. */ -namespace ActiveCollab\DatabaseConnection\Test; +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Test\Base; use mysqli; use RuntimeException; -use PHPUnit\Framework\TestCase as BaseTestCase; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -abstract class TestCase extends BaseTestCase +abstract class DbLinkedTestCase extends TestCase { - /** - * @var mysqli - */ - protected $link; - - /** - * Set up test environment. - */ + protected mysqli $link; + public function setUp(): void { parent::setUp(); @@ -44,9 +36,6 @@ public function setUp(): void } } - /** - * Tear down test environment. - */ public function tearDown(): void { $this->link->close(); diff --git a/test/src/Base/TestCase.php b/test/src/Base/TestCase.php new file mode 100644 index 0000000..9c7f849 --- /dev/null +++ b/test/src/Base/TestCase.php @@ -0,0 +1,20 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Test\Base; + +use PHPUnit\Framework\TestCase as BaseTestCase; + +abstract class TestCase extends BaseTestCase +{ +} diff --git a/test/src/BatchInsertTest.php b/test/src/BatchInsertTest.php index 812f1c5..ce99cb4 100644 --- a/test/src/BatchInsertTest.php +++ b/test/src/BatchInsertTest.php @@ -9,34 +9,23 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; use ActiveCollab\DatabaseConnection\BatchInsert\BatchInsert; use ActiveCollab\DatabaseConnection\BatchInsert\BatchInsertInterface; -use ActiveCollab\DatabaseConnection\Connection; use ActiveCollab\DatabaseConnection\ConnectionInterface; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; use DateTime; use RuntimeException; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class BatchInsertTest extends TestCase +class BatchInsertTest extends DbConnectedTestCase { - /** - * @var Connection - */ - private $connection; - - /** - * Set up test environment. - */ public function setUp(): void { parent::setUp(); - $this->connection = new Connection($this->link); - $create_table = $this->connection->execute("CREATE TABLE `writers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', @@ -47,9 +36,6 @@ public function setUp(): void $this->assertTrue($create_table); } - /** - * Tear down the test environment. - */ public function tearDown(): void { $this->connection->execute('DROP TABLE `writers`'); diff --git a/test/src/ConnectionFactoryTest.php b/test/src/ConnectionFactoryTest.php index ca5f074..2433be2 100644 --- a/test/src/ConnectionFactoryTest.php +++ b/test/src/ConnectionFactoryTest.php @@ -9,16 +9,16 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; use ActiveCollab\DatabaseConnection\ConnectionFactory; use ActiveCollab\DatabaseConnection\Exception\ConnectionException; +use ActiveCollab\DatabaseConnection\Test\Base\DbLinkedTestCase; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class ConnectionFactoryTest extends TestCase +class ConnectionFactoryTest extends DbLinkedTestCase { public function testExceptionOnInvalidArguments() { diff --git a/test/src/ContainerPropagatesToObjectTest.php b/test/src/ContainerPropagatesToObjectTest.php index da5c849..ba5843d 100644 --- a/test/src/ContainerPropagatesToObjectTest.php +++ b/test/src/ContainerPropagatesToObjectTest.php @@ -9,33 +9,25 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection; use ActiveCollab\DatabaseConnection\ConnectionInterface; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; use ActiveCollab\DatabaseConnection\Test\Fixture\Container; use ActiveCollab\DatabaseConnection\Test\Fixture\WriterWithContainer; use DateTime; use Psr\Container\ContainerInterface; -class ContainerPropagatesToObjectTest extends TestCase +class ContainerPropagatesToObjectTest extends DbConnectedTestCase { - /** - * @var ConnectionInterface - */ - private $connection; - - /** - * @var ContainerInterface - */ - private $container; + private ContainerInterface $container; public function setUp(): void { parent::setUp(); - $this->connection = new Connection\MysqliConnection($this->link); - if ($this->connection->tableExists('writers')) { $this->connection->dropTable('writers'); } @@ -69,7 +61,15 @@ public function tearDown(): void public function testExceptionWhenLoadingByObjectClassAndClassNameIsEmpty() { /** @var WriterWithContainer[] $result */ - $result = $this->connection->advancedExecute('SELECT * FROM `writers` ORDER BY `id`', null, ConnectionInterface::LOAD_ALL_ROWS, ConnectionInterface::RETURN_OBJECT_BY_CLASS, WriterWithContainer::class, null, $this->container); + $result = $this->connection->advancedExecute( + 'SELECT * FROM `writers` ORDER BY `id`', + null, + ConnectionInterface::LOAD_ALL_ROWS, + ConnectionInterface::RETURN_OBJECT_BY_CLASS, + WriterWithContainer::class, + null, + $this->container + ); $this->assertCount(3, $result); diff --git a/test/src/CountTest.php b/test/src/CountTest.php index 1388cf2..cd339cf 100644 --- a/test/src/CountTest.php +++ b/test/src/CountTest.php @@ -9,30 +9,19 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; use DateTime; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class CountTest extends TestCase +class CountTest extends DbConnectedTestCase { - /** - * @var Connection - */ - private $connection; - - /** - * Set up test environment. - */ public function setUp(): void { parent::setUp(); - $this->connection = new Connection($this->link); - $create_table = $this->connection->execute("CREATE TABLE `writers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', diff --git a/test/src/DatabasesTest.php b/test/src/DatabasesTest.php index 35f5741..81e096a 100644 --- a/test/src/DatabasesTest.php +++ b/test/src/DatabasesTest.php @@ -9,30 +9,14 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class DatabasesTest extends TestCase +class DatabasesTest extends DbConnectedTestCase { - /** - * @var MysqliConnection - */ - private $connection; - - /** - * Set up test environment. - */ - public function setUp(): void - { - parent::setUp(); - - $this->connection = new MysqliConnection($this->link); - } - /** * Test database exists call. */ diff --git a/test/src/DeleteTest.php b/test/src/DeleteTest.php index 864a937..1052da3 100644 --- a/test/src/DeleteTest.php +++ b/test/src/DeleteTest.php @@ -9,31 +9,20 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; use DateTime; use InvalidArgumentException; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class DeleteTest extends TestCase +class DeleteTest extends DbConnectedTestCase { - /** - * @var Connection - */ - private $connection; - - /** - * Set up test environment. - */ public function setUp(): void { parent::setUp(); - $this->connection = new Connection($this->link); - $this->connection->execute('DROP TABLE IF EXISTS `writers`'); $create_table = $this->connection->execute("CREATE TABLE `writers` ( diff --git a/test/src/EscapeTest.php b/test/src/EscapeTest.php index 4e2e33f..dc2d091 100644 --- a/test/src/EscapeTest.php +++ b/test/src/EscapeTest.php @@ -9,32 +9,19 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; use ActiveCollab\DateValue\DateTimeValue; use ActiveCollab\DateValue\DateValue; use DateTime; use DateTimeZone; use InvalidArgumentException; -class EscapeTest extends TestCase +class EscapeTest extends DbConnectedTestCase { - /** - * @var Connection - */ - private $connection; - - /** - * Set up test environment. - */ - public function setUp(): void - { - parent::setUp(); - - $this->connection = new Connection($this->link); - } - /** * Test escape NULL. */ diff --git a/test/src/ExecuteFromFileTest.php b/test/src/ExecuteFromFileTest.php index d83acd1..eb56ef3 100644 --- a/test/src/ExecuteFromFileTest.php +++ b/test/src/ExecuteFromFileTest.php @@ -14,9 +14,10 @@ namespace ActiveCollab\DatabaseConnection\Test; use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; +use ActiveCollab\DatabaseConnection\Test\Base\DbLinkedTestCase; use RuntimeException; -class ExecuteFromFileTest extends TestCase +class ExecuteFromFileTest extends DbLinkedTestCase { private MysqliConnection $connection; diff --git a/test/src/ExecuteLoadObjectTest.php b/test/src/ExecuteLoadObjectTest.php index 3045a10..b321714 100644 --- a/test/src/ExecuteLoadObjectTest.php +++ b/test/src/ExecuteLoadObjectTest.php @@ -9,32 +9,23 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection; -use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; use ActiveCollab\DatabaseConnection\ConnectionInterface; use ActiveCollab\DatabaseConnection\Result\Result; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; use ActiveCollab\DatabaseConnection\Test\Fixture\Writer; use DateTime; use InvalidArgumentException; -class ExecuteLoadObjectTest extends TestCase +class ExecuteLoadObjectTest extends DbConnectedTestCase { - /** - * @var Connection - */ - private $connection; - - /** - * Set up test environment. - */ public function setUp(): void { parent::setUp(); - $this->connection = new MysqliConnection($this->link); - if ($this->connection->tableExists('writers')) { $this->connection->dropTable('writers'); } diff --git a/test/src/ExecuteTest.php b/test/src/ExecuteTest.php index 12476be..36de69f 100644 --- a/test/src/ExecuteTest.php +++ b/test/src/ExecuteTest.php @@ -9,32 +9,21 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection; use ActiveCollab\DatabaseConnection\Exception\QueryException; use ActiveCollab\DatabaseConnection\Record\ValueCaster; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; use DateTime; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class ExecuteTest extends TestCase +class ExecuteTest extends DbConnectedTestCase { - /** - * @var Connection - */ - private $connection; - - /** - * Set up test environment. - */ public function setUp(): void { parent::setUp(); - $this->connection = new Connection($this->link); - $create_table = $this->connection->execute("CREATE TABLE `writers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', diff --git a/test/src/FieldsTest.php b/test/src/FieldsTest.php index 13d8062..6bc50c0 100644 --- a/test/src/FieldsTest.php +++ b/test/src/FieldsTest.php @@ -9,30 +9,19 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; use ActiveCollab\DatabaseConnection\Exception\QueryException; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class FieldsTest extends TestCase +class FieldsTest extends DbConnectedTestCase { - /** - * @var MysqliConnection - */ - private $connection; - - /** - * Set up test environment. - */ public function setUp(): void { parent::setUp(); - $this->connection = new MysqliConnection($this->link); - $this->connection->execute('DROP TABLE IF EXISTS `writers`'); $this->connection->execute("CREATE TABLE `writers` ( `id` int(11) NOT NULL AUTO_INCREMENT, diff --git a/test/src/Fixture/Container.php b/test/src/Fixture/Container.php index 7155612..d00759d 100644 --- a/test/src/Fixture/Container.php +++ b/test/src/Fixture/Container.php @@ -9,14 +9,13 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test\Fixture; use InvalidArgumentException; use Psr\Container\ContainerInterface; -/** - * @package ActiveCollab\DatabaseObject\Test\Fixtures - */ class Container extends \Pimple\Container implements ContainerInterface { /** diff --git a/test/src/Fixture/Writer.php b/test/src/Fixture/Writer.php index 74f0343..9570cd9 100644 --- a/test/src/Fixture/Writer.php +++ b/test/src/Fixture/Writer.php @@ -9,6 +9,8 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test\Fixture; use ActiveCollab\DatabaseConnection\Record\LoadFromRow; diff --git a/test/src/Fixture/WriterWithContainer.php b/test/src/Fixture/WriterWithContainer.php index 946ddb4..34849e6 100644 --- a/test/src/Fixture/WriterWithContainer.php +++ b/test/src/Fixture/WriterWithContainer.php @@ -9,15 +9,15 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test\Fixture; use ActiveCollab\ContainerAccess\ContainerAccessInterface; use ActiveCollab\ContainerAccess\ContainerAccessInterface\Implementation as ContainerAccessInterfaceImplementation; /** - * @property string $dependency - * - * @package ActiveCollab\DatabaseConnection\Test\Fixture + * @property string $dependency */ class WriterWithContainer extends Writer implements ContainerAccessInterface { diff --git a/test/src/ForeignKeysTest.php b/test/src/ForeignKeysTest.php index 3a782e3..761886b 100644 --- a/test/src/ForeignKeysTest.php +++ b/test/src/ForeignKeysTest.php @@ -15,8 +15,9 @@ use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; use ActiveCollab\DatabaseConnection\Exception\QueryException; +use ActiveCollab\DatabaseConnection\Test\Base\DbLinkedTestCase; -class ForeignKeysTest extends TestCase +class ForeignKeysTest extends DbLinkedTestCase { private MysqliConnection $connection; diff --git a/test/src/IndexesTest.php b/test/src/IndexesTest.php index b2b053d..c8ff1cf 100644 --- a/test/src/IndexesTest.php +++ b/test/src/IndexesTest.php @@ -9,15 +9,15 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; use ActiveCollab\DatabaseConnection\Exception\QueryException; +use ActiveCollab\DatabaseConnection\Test\Base\DbLinkedTestCase; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class IndexesTest extends TestCase +class IndexesTest extends DbLinkedTestCase { private MysqliConnection $connection; diff --git a/test/src/InsertTest.php b/test/src/InsertTest.php index 571a23e..04d4352 100644 --- a/test/src/InsertTest.php +++ b/test/src/InsertTest.php @@ -9,31 +9,20 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection; use ActiveCollab\DatabaseConnection\ConnectionInterface; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; use DateTime; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class InsertTest extends TestCase +class InsertTest extends DbConnectedTestCase { - /** - * @var Connection - */ - private $connection; - - /** - * Set up test environment. - */ public function setUp(): void { parent::setUp(); - $this->connection = new Connection($this->link); - $this->connection->execute('DROP TABLE IF EXISTS `writers`'); $create_table = $this->connection->execute("CREATE TABLE `writers` ( diff --git a/test/src/PrepareTest.php b/test/src/PrepareTest.php index 9c7017d..559a0e6 100644 --- a/test/src/PrepareTest.php +++ b/test/src/PrepareTest.php @@ -9,30 +9,14 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class PrepareTest extends TestCase +class PrepareTest extends DbConnectedTestCase { - /** - * @var Connection - */ - private $connection; - - /** - * Set up test environment. - */ - public function setUp(): void - { - parent::setUp(); - - $this->connection = new Connection($this->link); - } - /** * Test that prepare work when there are no arguments. */ diff --git a/test/src/QueryLoggingTest.php b/test/src/QueryLoggingTest.php index 71df76a..2cb6f16 100644 --- a/test/src/QueryLoggingTest.php +++ b/test/src/QueryLoggingTest.php @@ -9,27 +9,14 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; -class QueryLoggingTest extends TestCase +class QueryLoggingTest extends DbConnectedTestCase { - /** - * @var Connection - */ - private $connection; - - /** - * Set up test environment. - */ - public function setUp(): void - { - parent::setUp(); - - $this->connection = new Connection($this->link); - } - /** * Test if callback query log callback is working properly. */ diff --git a/test/src/SelectTest.php b/test/src/SelectTest.php index 6a10bae..cab644f 100644 --- a/test/src/SelectTest.php +++ b/test/src/SelectTest.php @@ -9,32 +9,21 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; use ActiveCollab\DatabaseConnection\Result\ResultInterface; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; use DateTime; use InvalidArgumentException; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class SelectTest extends TestCase +class SelectTest extends DbConnectedTestCase { - /** - * @var MysqliConnection - */ - private $connection; - - /** - * Set up test environment. - */ public function setUp(): void { parent::setUp(); - $this->connection = new MysqliConnection($this->link); - $create_table = $this->connection->execute("CREATE TABLE `writers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', diff --git a/test/src/Spatial/LineStringTest.php b/test/src/Spatial/LineStringTest.php new file mode 100644 index 0000000..0d32d12 --- /dev/null +++ b/test/src/Spatial/LineStringTest.php @@ -0,0 +1,53 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Test\Spatial; + +use ActiveCollab\DatabaseConnection\Spatial\Coordinate\Coordinate; +use ActiveCollab\DatabaseConnection\Spatial\LineString\LineString; +use ActiveCollab\DatabaseConnection\Spatial\LineString\LineStringInterface; +use ActiveCollab\DatabaseConnection\Spatial\Point\Point; +use ActiveCollab\DatabaseConnection\Test\Base\TestCase; +use LogicException; + +class LineStringTest extends TestCase +{ + public function testWillRequireAtLeastTwoPoints(): void + { + $this->expectException(LogicException::class); + $this->expectExceptionMessage('At least two points are required.'); + + new LineString( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + ); + } + + public function testWillCreateLineString(): void + { + $line_string = new LineString( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + new Point(new Coordinate(18.466), new Coordinate(-66.118)), + new Point(new Coordinate(32.321), new Coordinate(-64.757)), + ); + $this->assertInstanceOf(LineStringInterface::class, $line_string); + } + + public function testWillRenderWtk(): void + { + $this->assertSame( + 'LINESTRING(25.774 -80.19,18.466 -66.118,32.321 -64.757)', + (new LineString( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + new Point(new Coordinate(18.466), new Coordinate(-66.118)), + new Point(new Coordinate(32.321), new Coordinate(-64.757)), + ))->toWkt() + ); + } +} diff --git a/test/src/Spatial/LinearRingTest.php b/test/src/Spatial/LinearRingTest.php new file mode 100644 index 0000000..e7dc7fd --- /dev/null +++ b/test/src/Spatial/LinearRingTest.php @@ -0,0 +1,57 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Test\Spatial; + +use ActiveCollab\DatabaseConnection\Spatial\Point\Point; +use ActiveCollab\DatabaseConnection\Spatial\Coordinate\Coordinate; +use ActiveCollab\DatabaseConnection\Spatial\LinearRing\LinearRing; +use ActiveCollab\DatabaseConnection\Spatial\LinearRing\LinearRingInterface; +use ActiveCollab\DatabaseConnection\Test\Base\DbLinkedTestCase; +use LogicException; + +class LinearRingTest extends DbLinkedTestCase +{ + public function testWillRequireFourPoints(): void + { + $this->expectException(LogicException::class); + $this->expectExceptionMessage('At least four points are required.'); + + new LinearRing( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + new Point(new Coordinate(18.466), new Coordinate(-66.118)), + new Point(new Coordinate(32.321), new Coordinate(-64.757)), + ); + } + + public function testWilLRequireLinearRingToBeClosed(): void + { + $this->expectException(LogicException::class); + $this->expectExceptionMessage('Linear ring is not closed.'); + + new LinearRing( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + new Point(new Coordinate(18.466), new Coordinate(-66.118)), + new Point(new Coordinate(32.321), new Coordinate(-64.757)), + new Point(new Coordinate(32.321), new Coordinate(-64.757)), + ); + } + + public function testWillAcceptClosedLinearRing(): void + { + $linear_ring = new LinearRing( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + new Point(new Coordinate(18.466), new Coordinate(-66.118)), + new Point(new Coordinate(32.321), new Coordinate(-64.757)), + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + ); + $this->assertInstanceOf(LinearRingInterface::class, $linear_ring); + } +} diff --git a/test/src/Spatial/MultiLineStringTest.php b/test/src/Spatial/MultiLineStringTest.php new file mode 100644 index 0000000..945fbe5 --- /dev/null +++ b/test/src/Spatial/MultiLineStringTest.php @@ -0,0 +1,42 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Test\Spatial; + +use ActiveCollab\DatabaseConnection\Spatial\Coordinate\Coordinate; +use ActiveCollab\DatabaseConnection\Spatial\LineString\LineString; +use ActiveCollab\DatabaseConnection\Spatial\MultiLineString\MultiLineString; +use ActiveCollab\DatabaseConnection\Spatial\Point\Point; +use ActiveCollab\DatabaseConnection\Test\Base\TestCase; + +class MultiLineStringTest extends TestCase +{ + public function testWillRenderWtk(): void + { + $this->assertSame( + 'MULTILINESTRING((45.60317644 19.27315063,45.60312479 19.27319189,45.60473116 19.27750116,45.60478264 19.27745963),(45.60449426 19.27769178,45.60431683 19.27783455,45.60270942 19.27352285,45.60288728 19.27338113))', + (new MultiLineString( + new LineString( + new Point(new Coordinate(45.60317644), new Coordinate(19.27315063)), + new Point(new Coordinate(45.60312479), new Coordinate(19.27319189)), + new Point(new Coordinate(45.60473116), new Coordinate(19.27750116)), + new Point(new Coordinate(45.60478264), new Coordinate(19.27745963)), + ), + + new LineString( + new Point(new Coordinate(45.60449426), new Coordinate(19.27769178)), + new Point(new Coordinate(45.60431683), new Coordinate(19.27783455)), + new Point(new Coordinate(45.60270942), new Coordinate(19.27352285)), + new Point(new Coordinate(45.60288728), new Coordinate(19.27338113)), + ), + ))->toWkt() + ); + } +} diff --git a/test/src/Spatial/MultiPointTest.php b/test/src/Spatial/MultiPointTest.php new file mode 100644 index 0000000..9495822 --- /dev/null +++ b/test/src/Spatial/MultiPointTest.php @@ -0,0 +1,42 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Test\Spatial; + +use ActiveCollab\DatabaseConnection\Spatial\Coordinate\Coordinate; +use ActiveCollab\DatabaseConnection\Spatial\MultiPoint\MultiPoint; +use ActiveCollab\DatabaseConnection\Spatial\Point\Point; +use ActiveCollab\DatabaseConnection\Test\Base\DbLinkedTestCase; +use LogicException; + +class MultiPointTest extends DbLinkedTestCase +{ + public function testWillRequireTwoPoints(): void + { + $this->expectException(LogicException::class); + $this->expectExceptionMessage('At least two points are required.'); + + new MultiPoint( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + ); + } + + public function testWillRenderWtk(): void + { + $this->assertSame( + 'MULTIPOINT(25.774 -80.19,18.466 -66.118,32.321 -64.757)', + (new MultiPoint( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + new Point(new Coordinate(18.466), new Coordinate(-66.118)), + new Point(new Coordinate(32.321), new Coordinate(-64.757)), + ))->toWkt() + ); + } +} diff --git a/test/src/Spatial/MultiPolygonTest.php b/test/src/Spatial/MultiPolygonTest.php new file mode 100644 index 0000000..7e35620 --- /dev/null +++ b/test/src/Spatial/MultiPolygonTest.php @@ -0,0 +1,49 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Test\Spatial; + +use ActiveCollab\DatabaseConnection\Spatial\Coordinate\Coordinate; +use ActiveCollab\DatabaseConnection\Spatial\LinearRing\LinearRing; +use ActiveCollab\DatabaseConnection\Spatial\MultiPolygon\MultiPolygon; +use ActiveCollab\DatabaseConnection\Spatial\Point\Point; +use ActiveCollab\DatabaseConnection\Spatial\Polygon\Polygon; +use ActiveCollab\DatabaseConnection\Test\Base\TestCase; + +class MultiPolygonTest extends TestCase +{ + public function testWillRenderWtk(): void + { + $this->assertSame( + 'MULTIPOLYGON(((45.60317644 19.27315063,45.60312479 19.27319189,45.60473116 19.27750116,45.60478264 19.27745963,45.60317644 19.27315063)),((45.60449426 19.27769178,45.60431683 19.27783455,45.60270942 19.27352285,45.60288728 19.27338113,45.60449426 19.27769178)))', + (new MultiPolygon( + new Polygon( + new LinearRing( + new Point(new Coordinate(45.60317644), new Coordinate(19.27315063)), + new Point(new Coordinate(45.60312479), new Coordinate(19.27319189)), + new Point(new Coordinate(45.60473116), new Coordinate(19.27750116)), + new Point(new Coordinate(45.60478264), new Coordinate(19.27745963)), + new Point(new Coordinate(45.60317644), new Coordinate(19.27315063)), + ) + ), + + new Polygon( + new LinearRing( + new Point(new Coordinate(45.60449426), new Coordinate(19.27769178)), + new Point(new Coordinate(45.60431683), new Coordinate(19.27783455)), + new Point(new Coordinate(45.60270942), new Coordinate(19.27352285)), + new Point(new Coordinate(45.60288728), new Coordinate(19.27338113)), + new Point(new Coordinate(45.60449426), new Coordinate(19.27769178)), + ) + ) + ))->toWkt() + ); + } +} diff --git a/test/src/Spatial/PointTest.php b/test/src/Spatial/PointTest.php new file mode 100644 index 0000000..f77ee4a --- /dev/null +++ b/test/src/Spatial/PointTest.php @@ -0,0 +1,26 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Test\Spatial; + +use ActiveCollab\DatabaseConnection\Spatial\Coordinate\Coordinate; +use ActiveCollab\DatabaseConnection\Spatial\Point\Point; +use ActiveCollab\DatabaseConnection\Test\Base\TestCase; + +class PointTest extends TestCase +{ + public function testWillRenderWtk(): void + { + $this->assertSame( + 'POINT(25.774 -80.19)', + (new Point(new Coordinate(25.774), new Coordinate(-80.19)))->toWkt() + ); + } +} diff --git a/test/src/Spatial/PolygonTest.php b/test/src/Spatial/PolygonTest.php new file mode 100644 index 0000000..26d8c2f --- /dev/null +++ b/test/src/Spatial/PolygonTest.php @@ -0,0 +1,35 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Test\Spatial; + +use ActiveCollab\DatabaseConnection\Spatial\Coordinate\Coordinate; +use ActiveCollab\DatabaseConnection\Spatial\LinearRing\LinearRing; +use ActiveCollab\DatabaseConnection\Spatial\Point\Point; +use ActiveCollab\DatabaseConnection\Spatial\Polygon\Polygon; +use ActiveCollab\DatabaseConnection\Test\Base\TestCase; + +class PolygonTest extends TestCase +{ + public function testWillRenderWtk(): void + { + $this->assertSame( + 'POLYGON((25.774 -80.19,18.466 -66.118,32.321 -64.757,25.774 -80.19))', + (new Polygon( + new LinearRing( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + new Point(new Coordinate(18.466), new Coordinate(-66.118)), + new Point(new Coordinate(32.321), new Coordinate(-64.757)), + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + ) + ))->toWkt() + ); + } +} diff --git a/test/src/Spatial/SpatialColumnsTest.php b/test/src/Spatial/SpatialColumnsTest.php new file mode 100644 index 0000000..23f2e32 --- /dev/null +++ b/test/src/Spatial/SpatialColumnsTest.php @@ -0,0 +1,384 @@ +. All rights reserved. + */ + +declare(strict_types=1); + +namespace ActiveCollab\DatabaseConnection\Test\Spatial; + +use ActiveCollab\DatabaseConnection\Record\ValueCaster; +use ActiveCollab\DatabaseConnection\Record\ValueCasterInterface; +use ActiveCollab\DatabaseConnection\Result\ResultInterface; +use ActiveCollab\DatabaseConnection\Spatial\LineString\LineString; +use ActiveCollab\DatabaseConnection\Spatial\LineString\LineStringInterface; +use ActiveCollab\DatabaseConnection\Spatial\MultiLineString\MultiLineString; +use ActiveCollab\DatabaseConnection\Spatial\MultiLineString\MultiLineStringInterface; +use ActiveCollab\DatabaseConnection\Spatial\MultiPoint\MultiPoint; +use ActiveCollab\DatabaseConnection\Spatial\MultiPoint\MultiPointInterface; +use ActiveCollab\DatabaseConnection\Spatial\MultiPolygon\MultiPolygon; +use ActiveCollab\DatabaseConnection\Spatial\MultiPolygon\MultiPolygonInterface; +use ActiveCollab\DatabaseConnection\Spatial\Point\Point; +use ActiveCollab\DatabaseConnection\Spatial\Coordinate\Coordinate; +use ActiveCollab\DatabaseConnection\Spatial\LinearRing\LinearRing; +use ActiveCollab\DatabaseConnection\Spatial\Point\PointInterface; +use ActiveCollab\DatabaseConnection\Spatial\Polygon\Polygon; +use ActiveCollab\DatabaseConnection\Spatial\Polygon\PolygonInterface; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; + +class SpatialColumnsTest extends DbConnectedTestCase +{ + public function tearDown(): void + { + $this->connection->dropTable('points'); + $this->connection->dropTable('multi_points'); + $this->connection->dropTable('line_strings'); + $this->connection->dropTable('multi_line_strings'); + $this->connection->dropTable('polygons'); + $this->connection->dropTable('multi_polygons'); + + parent::tearDown(); + } + + public function testWillReadAndWritePoint(): void + { + $create_table = $this->connection->execute("CREATE TABLE IF NOT EXISTS `points` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `point` POINT NOT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"); + + $this->assertTrue($create_table); + + $point_to_write = new Point(new Coordinate(25.774), new Coordinate(-80.19)); + + $inserted = $this->connection->insert( + 'points', + [ + 'point' => $point_to_write, + ] + ); + + $this->assertSame(1, $inserted); + + $rows = $this->connection->execute('SELECT `id`, ST_AsText(`point`) AS "point" FROM `points`'); + $this->assertInstanceOf(ResultInterface::class, $rows); + + $rows->setValueCaster( + new ValueCaster( + [ + 'point' => ValueCasterInterface::CAST_SPATIAL, + ] + ) + ); + + $first_row = $rows[0]; + + $this->assertInstanceOf(PointInterface::class, $first_row['point']); + + /** @var PointInterface $read_point */ + $read_point = $first_row['point']; + + $this->assertTrue($read_point->isSame($point_to_write)); + } + + public function testWillReadAndWriteMultiPoint(): void + { + $create_table = $this->connection->execute("CREATE TABLE IF NOT EXISTS `multi_points` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `multi_point` MULTIPOINT NOT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"); + + $this->assertTrue($create_table); + + $multi_point_to_write = new MultiPoint( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + new Point(new Coordinate(18.466), new Coordinate(-66.118)), + new Point(new Coordinate(32.321), new Coordinate(-64.757)), + ); + + $inserted = $this->connection->insert( + 'multi_points', + [ + 'multi_point' => $multi_point_to_write, + ] + ); + + $this->assertSame(1, $inserted); + + $rows = $this->connection->execute('SELECT `id`, ST_AsText(`multi_point`) AS "multi_point" FROM `multi_points`'); + $this->assertInstanceOf(ResultInterface::class, $rows); + + $rows->setValueCaster( + new ValueCaster( + [ + 'multi_point' => ValueCasterInterface::CAST_SPATIAL, + ] + ) + ); + + $first_row = $rows[0]; + + $this->assertInstanceOf(MultiPointInterface::class, $first_row['multi_point']); + + /** @var MultiPointInterface $read_multi_point */ + $read_multi_point = $first_row['multi_point']; + + foreach ($read_multi_point->getPoints() as $k => $read_point) { + $this->assertTrue( + $read_point->isSame( + $multi_point_to_write->getPoints()[$k] + ) + ); + } + } + + public function testWillReadAndWriteLineString(): void + { + $create_table = $this->connection->execute("CREATE TABLE IF NOT EXISTS `line_strings` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `line_string` LINESTRING NOT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"); + + $this->assertTrue($create_table); + + $line_string_to_write = new LineString( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + new Point(new Coordinate(18.466), new Coordinate(-66.118)), + new Point(new Coordinate(32.321), new Coordinate(-64.757)), + ); + + $inserted = $this->connection->insert( + 'line_strings', + [ + 'line_string' => $line_string_to_write, + ] + ); + + $this->assertSame(1, $inserted); + + $rows = $this->connection->execute('SELECT `id`, ST_AsText(`line_string`) AS "line_string" FROM `line_strings`'); + $this->assertInstanceOf(ResultInterface::class, $rows); + + $rows->setValueCaster( + new ValueCaster( + [ + 'line_string' => ValueCasterInterface::CAST_SPATIAL, + ] + ) + ); + + $first_row = $rows[0]; + + $this->assertInstanceOf(LineStringInterface::class, $first_row['line_string']); + + /** @var LineStringInterface $read_line_string */ + $read_line_string = $first_row['line_string']; + + foreach ($read_line_string->getPoints() as $k => $read_coordinate) { + $this->assertTrue( + $read_coordinate->isSame( + $line_string_to_write->getPoints()[$k] + ) + ); + } + } + + public function testWillReadAndWriteMultiLineString(): void + { + $create_table = $this->connection->execute("CREATE TABLE IF NOT EXISTS `multi_line_strings` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `multi_line_string` MULTILINESTRING NOT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"); + + $this->assertTrue($create_table); + + $multi_line_string_to_write = new MultiLineString( + new LineString( + new Point(new Coordinate(45.60317644), new Coordinate(19.27315063)), + new Point(new Coordinate(45.60312479), new Coordinate(19.27319189)), + new Point(new Coordinate(45.60473116), new Coordinate(19.27750116)), + new Point(new Coordinate(45.60478264), new Coordinate(19.27745963)), + ), + + new LineString( + new Point(new Coordinate(45.60449426), new Coordinate(19.27769178)), + new Point(new Coordinate(45.60431683), new Coordinate(19.27783455)), + new Point(new Coordinate(45.60270942), new Coordinate(19.27352285)), + new Point(new Coordinate(45.60288728), new Coordinate(19.27338113)), + ), + ); + + $inserted = $this->connection->insert( + 'multi_line_strings', + [ + 'multi_line_string' => $multi_line_string_to_write, + ] + ); + + $this->assertSame(1, $inserted); + + $rows = $this->connection->execute( + 'SELECT `id`, ST_AsText(`multi_line_string`) AS "multi_line_string" FROM `multi_line_strings`' + ); + $this->assertInstanceOf(ResultInterface::class, $rows); + + $rows->setValueCaster( + new ValueCaster( + [ + 'multi_line_string' => ValueCasterInterface::CAST_SPATIAL, + ] + ) + ); + + $first_row = $rows[0]; + + $this->assertInstanceOf(MultiLineStringInterface::class, $first_row['multi_line_string']); + + /** @var MultiLineStringInterface $read_multi_line_strings */ + $read_multi_line_strings = $first_row['multi_line_string']; + + foreach ($read_multi_line_strings as $k => $read_multi_line_string) { + foreach ($read_multi_line_string->getPoints() as $j => $read_point) { + $this->assertTrue( + $read_point->isSame( + $multi_line_string_to_write->getLines()[$k]->getPoints()[$j] + ) + ); + } + } + } + + public function testWillReadAndWritePolygon(): void + { + $create_table = $this->connection->execute("CREATE TABLE IF NOT EXISTS `polygons` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `polygon` POLYGON NOT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"); + + $this->assertTrue($create_table); + + $polygon_to_write = new Polygon( + new LinearRing( + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + new Point(new Coordinate(18.466), new Coordinate(-66.118)), + new Point(new Coordinate(32.321), new Coordinate(-64.757)), + new Point(new Coordinate(25.774), new Coordinate(-80.19)), + ) + ); + + $inserted = $this->connection->insert( + 'polygons', + [ + 'polygon' => $polygon_to_write, + ] + ); + + $this->assertSame(1, $inserted); + + $rows = $this->connection->execute('SELECT `id`, ST_AsText(`polygon`) AS "polygon" FROM `polygons`'); + $this->assertInstanceOf(ResultInterface::class, $rows); + + $rows->setValueCaster( + new ValueCaster( + [ + 'polygon' => ValueCasterInterface::CAST_SPATIAL, + ] + ) + ); + + $first_row = $rows[0]; + + $this->assertInstanceOf(PolygonInterface::class, $first_row['polygon']); + + /** @var PolygonInterface $read_polygon */ + $read_polygon = $first_row['polygon']; + + foreach ($read_polygon->getExteriorBoundary()->getPoints() as $k => $read_coordinate) { + $this->assertTrue( + $read_coordinate->isSame( + $polygon_to_write->getExteriorBoundary()->getPoints()[$k] + ) + ); + } + } + + public function testWillReadAndWriteMultiPolygon(): void + { + $this->connection->dropTable('multi_polygons'); + + $create_table = $this->connection->execute("CREATE TABLE IF NOT EXISTS `multi_polygons` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `multi_polygon` MULTIPOLYGON NOT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"); + + $this->assertTrue($create_table); + + $multi_polygon_to_write = new MultiPolygon( + new Polygon( + new LinearRing( + new Point(new Coordinate(45.60317644), new Coordinate(19.27315063)), + new Point(new Coordinate(45.60312479), new Coordinate(19.27319189)), + new Point(new Coordinate(45.60473116), new Coordinate(19.27750116)), + new Point(new Coordinate(45.60478264), new Coordinate(19.27745963)), + new Point(new Coordinate(45.60317644), new Coordinate(19.27315063)), + ) + ), + + new Polygon( + new LinearRing( + new Point(new Coordinate(45.60449426), new Coordinate(19.27769178)), + new Point(new Coordinate(45.60431683), new Coordinate(19.27783455)), + new Point(new Coordinate(45.60270942), new Coordinate(19.27352285)), + new Point(new Coordinate(45.60288728), new Coordinate(19.27338113)), + new Point(new Coordinate(45.60449426), new Coordinate(19.27769178)), + ) + ) + ); + + $inserted = $this->connection->insert( + 'multi_polygons', + [ + 'multi_polygon' => $multi_polygon_to_write, + ] + ); + + $this->assertSame(1, $inserted); + + $rows = $this->connection->execute('SELECT `id`, ST_AsText(`multi_polygon`) AS "multi_polygon" FROM `multi_polygons`'); + $this->assertInstanceOf(ResultInterface::class, $rows); + + $rows->setValueCaster( + new ValueCaster( + [ + 'multi_polygon' => ValueCasterInterface::CAST_SPATIAL, + ] + ) + ); + + $first_row = $rows[0]; + + $this->assertInstanceOf(MultiPolygonInterface::class, $first_row['multi_polygon']); + + /** @var MultiPolygonInterface $read_multi_polygon */ + $read_multi_polygon = $first_row['multi_polygon']; + + foreach ($read_multi_polygon as $k => $polygon) { + foreach ($polygon->getExteriorBoundary()->getCoordinates() as $j => $read_coordinate) { + $this->assertTrue( + $read_coordinate->isSame( + $multi_polygon_to_write->getPolygons()[$k]->getExteriorBoundary()->getPoints()[$j] + ) + ); + } + } + } +} diff --git a/test/src/TablesTest.php b/test/src/TablesTest.php index 235934f..2bd36ac 100644 --- a/test/src/TablesTest.php +++ b/test/src/TablesTest.php @@ -9,29 +9,18 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class TablesTest extends TestCase +class TablesTest extends DbConnectedTestCase { - /** - * @var MysqliConnection - */ - private $connection; - - /** - * Set up test environment. - */ public function setUp(): void { parent::setUp(); - $this->connection = new MysqliConnection($this->link); - $this->connection->execute('DROP TABLE IF EXISTS `writers1`'); $this->connection->execute("CREATE TABLE `writers1` ( `id` int(11) NOT NULL AUTO_INCREMENT, diff --git a/test/src/TransactionsTest.php b/test/src/TransactionsTest.php index c140f13..833c9f1 100644 --- a/test/src/TransactionsTest.php +++ b/test/src/TransactionsTest.php @@ -9,29 +9,21 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; use DateTime; use Exception; use RuntimeException; -class TransactionsTest extends TestCase +class TransactionsTest extends DbConnectedTestCase { - /** - * @var Connection - */ - private $connection; - - /** - * Set up test environment. - */ public function setUp(): void { parent::setUp(); - $this->connection = new Connection($this->link); - $create_table = $this->connection->execute("CREATE TABLE `writers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', @@ -147,8 +139,6 @@ public function testTransactClosure() /** * Test if transaction closure propagates exception thrown within. - * - * */ public function testRollbackTransactClosure() { diff --git a/test/src/UpdateTest.php b/test/src/UpdateTest.php index a2be03b..23212f7 100644 --- a/test/src/UpdateTest.php +++ b/test/src/UpdateTest.php @@ -9,31 +9,20 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; use DateTime; use InvalidArgumentException; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class UpdateTest extends TestCase +class UpdateTest extends DbConnectedTestCase { - /** - * @var MysqliConnection - */ - private $connection; - - /** - * Set up test environment. - */ public function setUp(): void { parent::setUp(); - $this->connection = new MysqliConnection($this->link); - $this->connection->execute('DROP TABLE IF EXISTS `writers`'); $create_table = $this->connection->execute("CREATE TABLE `writers` ( diff --git a/test/src/UsersTest.php b/test/src/UsersTest.php index 724dce5..3ca4128 100644 --- a/test/src/UsersTest.php +++ b/test/src/UsersTest.php @@ -9,30 +9,14 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; -use ActiveCollab\DatabaseConnection\Connection\MysqliConnection; +use ActiveCollab\DatabaseConnection\Test\Base\DbConnectedTestCase; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class UsersTest extends TestCase +class UsersTest extends DbConnectedTestCase { - /** - * @var MysqliConnection - */ - private $connection; - - /** - * Set up test environment. - */ - public function setUp(): void - { - parent::setUp(); - - $this->connection = new MysqliConnection($this->link); - } - /** * Test user exists call. */ diff --git a/test/src/ValueCasterTest.php b/test/src/ValueCasterTest.php index 5b71164..5a17ccf 100644 --- a/test/src/ValueCasterTest.php +++ b/test/src/ValueCasterTest.php @@ -9,18 +9,18 @@ * with this source code in the file LICENSE. */ +declare(strict_types=1); + namespace ActiveCollab\DatabaseConnection\Test; use ActiveCollab\DatabaseConnection\Record\ValueCaster; use ActiveCollab\DatabaseConnection\Record\ValueCasterInterface; +use ActiveCollab\DatabaseConnection\Test\Base\DbLinkedTestCase; use ActiveCollab\DateValue\DateTimeValueInterface; use ActiveCollab\DateValue\DateValueInterface; use RuntimeException; -/** - * @package ActiveCollab\DatabaseConnection\Test - */ -class ValueCasterTest extends TestCase +class ValueCasterTest extends DbLinkedTestCase { /** * Test default casters.