diff --git a/composer.json b/composer.json index e1713d9..04dee21 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "require": { "php": ">=8.3", "nette/di": "v3.*", - "nette/database": "v3.*", + "nette/database": "^v3.2.7", "ext-pdo": "*", "ext-gettext": "*" }, diff --git a/composer.lock b/composer.lock index 495e72e..207cc04 100644 --- a/composer.lock +++ b/composer.lock @@ -8,30 +8,30 @@ "packages": [ { "name": "nette/caching", - "version": "v3.3.1", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/nette/caching.git", - "reference": "b37d2c9647b41a9d04f099f10300dc5496c4eb77" + "reference": "a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/caching/zipball/b37d2c9647b41a9d04f099f10300dc5496c4eb77", - "reference": "b37d2c9647b41a9d04f099f10300dc5496c4eb77", + "url": "https://api.github.com/repos/nette/caching/zipball/a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d", + "reference": "a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d", "shasum": "" }, "require": { "nette/utils": "^4.0", - "php": "8.0 - 8.4" + "php": "8.1 - 8.5" }, "conflict": { - "latte/latte": ">=3.0.0 <3.0.12" + "latte/latte": "<3.0.12" }, "require-dev": { - "latte/latte": "^2.11 || ^3.0.12", + "latte/latte": "^3.0.12", "nette/di": "^3.1 || ^4.0", "nette/tester": "^2.4", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "psr/simple-cache": "^2.0 || ^3.0", "tracy/tracy": "^2.9" }, @@ -41,10 +41,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.3-dev" + "dev-master": "3.4-dev" } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -76,9 +79,9 @@ ], "support": { "issues": "https://github.com/nette/caching/issues", - "source": "https://github.com/nette/caching/tree/v3.3.1" + "source": "https://github.com/nette/caching/tree/v3.4.0" }, - "time": "2024-08-07T00:01:58+00:00" + "time": "2025-08-06T23:05:08+00:00" }, { "name": "nette/database", @@ -298,27 +301,27 @@ }, { "name": "nette/php-generator", - "version": "v4.1.8", + "version": "v4.2.0", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "42806049a7774a2bd316c958f5dcf01c6b5c56fa" + "reference": "4707546a1f11badd72f5d82af4f8a6bc64bd56ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/42806049a7774a2bd316c958f5dcf01c6b5c56fa", - "reference": "42806049a7774a2bd316c958f5dcf01c6b5c56fa", + "url": "https://api.github.com/repos/nette/php-generator/zipball/4707546a1f11badd72f5d82af4f8a6bc64bd56ac", + "reference": "4707546a1f11badd72f5d82af4f8a6bc64bd56ac", "shasum": "" }, "require": { - "nette/utils": "^3.2.9 || ^4.0", - "php": "8.0 - 8.4" + "nette/utils": "^4.0.6", + "php": "8.1 - 8.5" }, "require-dev": { - "jetbrains/phpstorm-attributes": "dev-master", + "jetbrains/phpstorm-attributes": "^1.2", "nette/tester": "^2.4", - "nikic/php-parser": "^4.18 || ^5.0", - "phpstan/phpstan": "^1.0", + "nikic/php-parser": "^5.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.8" }, "suggest": { @@ -327,10 +330,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -351,7 +357,7 @@ "homepage": "https://nette.org/contributors" } ], - "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.4 features.", + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.5 features.", "homepage": "https://nette.org", "keywords": [ "code", @@ -361,41 +367,44 @@ ], "support": { "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/v4.1.8" + "source": "https://github.com/nette/php-generator/tree/v4.2.0" }, - "time": "2025-03-31T00:29:29+00:00" + "time": "2025-08-06T18:24:31+00:00" }, { "name": "nette/robot-loader", - "version": "v4.0.3", + "version": "v4.1.0", "source": { "type": "git", "url": "https://github.com/nette/robot-loader.git", - "reference": "45d67753fb4865bb718e9a6c9be69cc9470137b7" + "reference": "805fb81376c24755d50bdb8bc69ca4db3def71d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/robot-loader/zipball/45d67753fb4865bb718e9a6c9be69cc9470137b7", - "reference": "45d67753fb4865bb718e9a6c9be69cc9470137b7", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/805fb81376c24755d50bdb8bc69ca4db3def71d1", + "reference": "805fb81376c24755d50bdb8bc69ca4db3def71d1", "shasum": "" }, "require": { "ext-tokenizer": "*", "nette/utils": "^4.0", - "php": "8.0 - 8.4" + "php": "8.1 - 8.5" }, "require-dev": { "nette/tester": "^2.4", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -427,9 +436,9 @@ ], "support": { "issues": "https://github.com/nette/robot-loader/issues", - "source": "https://github.com/nette/robot-loader/tree/v4.0.3" + "source": "https://github.com/nette/robot-loader/tree/v4.1.0" }, - "time": "2024-06-18T20:26:39+00:00" + "time": "2025-08-06T18:34:21+00:00" }, { "name": "nette/schema", @@ -495,29 +504,29 @@ }, { "name": "nette/utils", - "version": "v4.0.7", + "version": "v4.0.8", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "e67c4061eb40b9c113b218214e42cb5a0dda28f2" + "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/e67c4061eb40b9c113b218214e42cb5a0dda28f2", - "reference": "e67c4061eb40b9c113b218214e42cb5a0dda28f2", + "url": "https://api.github.com/repos/nette/utils/zipball/c930ca4e3cf4f17dcfb03037703679d2396d2ede", + "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede", "shasum": "" }, "require": { - "php": "8.0 - 8.4" + "php": "8.0 - 8.5" }, "conflict": { "nette/finder": "<3", "nette/schema": "<1.2.2" }, "require-dev": { - "jetbrains/phpstorm-attributes": "dev-master", + "jetbrains/phpstorm-attributes": "^1.2", "nette/tester": "^2.5", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "suggest": { @@ -535,6 +544,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -575,28 +587,28 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.7" + "source": "https://github.com/nette/utils/tree/v4.0.8" }, - "time": "2025-06-03T04:55:08+00:00" + "time": "2025-08-06T21:43:34+00:00" } ], "packages-dev": [ { "name": "nette/tester", - "version": "v2.5.5", + "version": "v2.5.6", "source": { "type": "git", "url": "https://github.com/nette/tester.git", - "reference": "4b8a8519307598b56142ea0567b2cedb474af3fc" + "reference": "f7328f743d06df233bbc9b68da9f4941f73ad661" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/tester/zipball/4b8a8519307598b56142ea0567b2cedb474af3fc", - "reference": "4b8a8519307598b56142ea0567b2cedb474af3fc", + "url": "https://api.github.com/repos/nette/tester/zipball/f7328f743d06df233bbc9b68da9f4941f73ad661", + "reference": "f7328f743d06df233bbc9b68da9f4941f73ad661", "shasum": "" }, "require": { - "php": "8.0 - 8.4" + "php": "8.0 - 8.5" }, "require-dev": { "ext-simplexml": "*", @@ -655,9 +667,9 @@ ], "support": { "issues": "https://github.com/nette/tester/issues", - "source": "https://github.com/nette/tester/tree/v2.5.5" + "source": "https://github.com/nette/tester/tree/v2.5.6" }, - "time": "2025-06-19T17:58:04+00:00" + "time": "2025-08-07T00:28:58+00:00" }, { "name": "phpstan/phpstan", diff --git a/src/Model/Model.php b/src/Model/Model.php index f0c4fdf..b16a10b 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -8,6 +8,7 @@ use Fykosak\NetteORM\ModelRelationsParser; use Fykosak\NetteORM\Selection\TypedGroupedSelection; use Fykosak\NetteORM\Selection\TypedSelection; +use Fykosak\NetteORM\Types\WGS84Point; use Nette\Database\Table\ActiveRow; use Nette\MemberAccessException; @@ -54,6 +55,8 @@ public function &__get(string $key): mixed //phpcs:ignore } } elseif ($returnType->isSubclassOf(\BackedEnum::class)) { $value = $returnType->getMethod('tryFrom')->invoke($returnType, $value); + } elseif ($returnType->name === WGS84Point::class) { + $value = $returnType->getMethod('fromBytes')->invoke($returnType, $value); } } } diff --git a/src/ModelRelationsParser.php b/src/ModelRelationsParser.php index 7d79ec0..bfd9ebd 100644 --- a/src/ModelRelationsParser.php +++ b/src/ModelRelationsParser.php @@ -13,7 +13,7 @@ class ModelRelationsParser { /** * @phpstan-param \ReflectionClass $modelReflection - * @phpstan-return array|null,property:string}> + * @phpstan-return array|null,property:string}> * @throws \ReflectionException */ public static function parseModelDoc(\ReflectionClass $modelReflection): ?array diff --git a/src/Selection/TypedGroupedSelection.php b/src/Selection/TypedGroupedSelection.php index 9eff661..0e7e9f1 100644 --- a/src/Selection/TypedGroupedSelection.php +++ b/src/Selection/TypedGroupedSelection.php @@ -13,7 +13,7 @@ use Nette\Database\Table\Selection; /** - * @template TModel of Model + * @phpstan-template-covariant TModel of Model */ class TypedGroupedSelection extends GroupedSelection { diff --git a/src/Selection/TypedSelection.php b/src/Selection/TypedSelection.php index 6bd50fa..e20a32d 100644 --- a/src/Selection/TypedSelection.php +++ b/src/Selection/TypedSelection.php @@ -12,7 +12,7 @@ use Nette\Database\Table\Selection; /** - * @template TModel of Model + * @phpstan-template-covariant TModel of Model * @phpstan-extends Selection * @phpstan-ignore-next-line */ diff --git a/src/Selection/TypedSelectionsTrait.php b/src/Selection/TypedSelectionsTrait.php index 4926241..9b87e31 100644 --- a/src/Selection/TypedSelectionsTrait.php +++ b/src/Selection/TypedSelectionsTrait.php @@ -8,7 +8,7 @@ use Fykosak\NetteORM\Model\Model; /** - * @template TModel of Model + * @phpstan-template-covariant TModel of Model */ trait TypedSelectionsTrait { diff --git a/src/Service/Service.php b/src/Service/Service.php index 79323f4..718beb3 100644 --- a/src/Service/Service.php +++ b/src/Service/Service.php @@ -7,6 +7,7 @@ use Fykosak\NetteORM\Mapper; use Fykosak\NetteORM\Model\Model; use Fykosak\NetteORM\Selection\TypedSelection; +use Fykosak\NetteORM\Types\WGS84Point; use Nette\Database\Explorer; /** @@ -104,7 +105,9 @@ protected function filterData(array $data): array $name = $column['name']; if (array_key_exists($name, $data)) { if ($data[$name] instanceof \BackedEnum) { - $result[$name] = $data[$name]->value; + $result[$name] = $data[$name]->value; + } elseif ($data[$name] instanceof WGS84Point) { + $result[$name] = $data[$name]->toString(); } else { $result[$name] = $data[$name]; } diff --git a/src/Types/WGS84Point.php b/src/Types/WGS84Point.php new file mode 100644 index 0000000..136987f --- /dev/null +++ b/src/Types/WGS84Point.php @@ -0,0 +1,84 @@ +floatToDeg(abs($value)); + if ($escape) { + return sprintf('%d° %d' %.2f" %s', $deg, $minutes, $seconds, $label); + } else { + return sprintf('%d° %d\' %.2f" %s', $deg, $minutes, $seconds, $label); + } + } + + public static function fromBytes(?string $data): ?self + { + if (!isset($data)) { + return null; + } + $parsed = unpack("Lsrid/cendian/Vtype/dx/dy", $data); + if ($parsed === false) { + throw new InvalidStateException(); + } + if ($parsed['srid'] !== self::GPSSRId) {//its GPS + throw new InvalidStateException(); + } + if ($parsed['endian'] !== self::TypEndian) { + throw new InvalidStateException(); + } + if ($parsed['type'] !== self::PointType) { + throw new InvalidStateException(); + } + return new self($parsed['x'], $parsed['y']); + } + + public function toString(): string + { + return pack( + 'LcVdd', + self::GPSSRId, + self::TypEndian, + self::PointType, + $this->longitude, + $this->latitude + ); + } +}