diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index 4a6e580..514bb8f 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -22,6 +22,7 @@ on:
env:
CONSUL_HTTP_ADDR: "127.0.0.1:8500"
+ CONSUL_VERSION: '1.16.1'
jobs:
tests:
@@ -33,22 +34,32 @@ jobs:
name: Tests - PHP ${{ matrix.php-version }}
steps:
- uses: actions/checkout@v3
+
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: json
ini-values: precision=14,serialize_precision=-1
- - run: |
+
+ - name: 'Composer update'
+ # language=bash
+ run: |
composer update \
--no-ansi \
--no-interaction \
--no-scripts \
--no-progress
- - run: |
- wget https://releases.hashicorp.com/consul/1.15.2/consul_1.15.2_linux_amd64.zip
- unzip consul_1.15.2_linux_amd64.zip -d /usr/local/bin/
- rm consul_1.15.2_linux_amd64.zip
+
+ - name: 'Install Consul'
+ # language=bash
+ run: |
+ wget https://releases.hashicorp.com/consul/${{ env.CONSUL_VERSION }}/consul_${{ env.CONSUL_VERSION }}_linux_amd64.zip
+ unzip consul_${{ env.CONSUL_VERSION }}_linux_amd64.zip -d /usr/local/bin/
+ rm consul_${{ env.CONSUL_VERSION }}_linux_amd64.zip
chmod +x /usr/local/bin/consul
consul --version
- - run: |
+
+ - name: 'Execute tests'
+ # language=bash
+ run: |
./vendor/bin/phpunit -c phpunit.xml
diff --git a/composer.lock b/composer.lock
index b519421..f06ad9b 100644
--- a/composer.lock
+++ b/composer.lock
@@ -235,16 +235,16 @@
},
{
"name": "guzzlehttp/promises",
- "version": "2.0.0",
+ "version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
- "reference": "3a494dc7dc1d7d12e511890177ae2d0e6c107da6"
+ "reference": "111166291a0f8130081195ac4556a5587d7f1b5d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/3a494dc7dc1d7d12e511890177ae2d0e6c107da6",
- "reference": "3a494dc7dc1d7d12e511890177ae2d0e6c107da6",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/111166291a0f8130081195ac4556a5587d7f1b5d",
+ "reference": "111166291a0f8130081195ac4556a5587d7f1b5d",
"shasum": ""
},
"require": {
@@ -298,7 +298,7 @@
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
- "source": "https://github.com/guzzle/promises/tree/2.0.0"
+ "source": "https://github.com/guzzle/promises/tree/2.0.1"
},
"funding": [
{
@@ -314,20 +314,20 @@
"type": "tidelift"
}
],
- "time": "2023-05-21T13:50:22+00:00"
+ "time": "2023-08-03T15:11:55+00:00"
},
{
"name": "guzzlehttp/psr7",
- "version": "2.5.0",
+ "version": "2.6.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
- "reference": "b635f279edd83fc275f822a1188157ffea568ff6"
+ "reference": "8bd7c33a0734ae1c5d074360512beb716bef3f77"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6",
- "reference": "b635f279edd83fc275f822a1188157ffea568ff6",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/8bd7c33a0734ae1c5d074360512beb716bef3f77",
+ "reference": "8bd7c33a0734ae1c5d074360512beb716bef3f77",
"shasum": ""
},
"require": {
@@ -414,7 +414,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
- "source": "https://github.com/guzzle/psr7/tree/2.5.0"
+ "source": "https://github.com/guzzle/psr7/tree/2.6.0"
},
"funding": [
{
@@ -430,7 +430,7 @@
"type": "tidelift"
}
],
- "time": "2023-04-17T16:11:26+00:00"
+ "time": "2023-08-03T15:06:02+00:00"
},
{
"name": "psr/http-client",
@@ -638,16 +638,16 @@
},
{
"name": "symfony/deprecation-contracts",
- "version": "v3.2.1",
+ "version": "v3.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e"
+ "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf",
+ "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf",
"shasum": ""
},
"require": {
@@ -656,7 +656,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "3.3-dev"
+ "dev-main": "3.4-dev"
},
"thanks": {
"name": "symfony/contracts",
@@ -685,7 +685,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.2.1"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0"
},
"funding": [
{
@@ -701,7 +701,7 @@
"type": "tidelift"
}
],
- "time": "2023-03-01T10:25:55+00:00"
+ "time": "2023-05-23T14:45:45+00:00"
}
],
"packages-dev": [
@@ -766,16 +766,16 @@
},
{
"name": "nikic/php-parser",
- "version": "v4.15.5",
+ "version": "v4.17.1",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e"
+ "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/11e2663a5bc9db5d714eedb4277ee300403b4a9e",
- "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
+ "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
"shasum": ""
},
"require": {
@@ -816,9 +816,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
- "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.5"
+ "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1"
},
- "time": "2023-05-19T20:20:00+00:00"
+ "time": "2023-08-13T19:53:39+00:00"
},
{
"name": "phar-io/manifest",
@@ -933,16 +933,16 @@
},
{
"name": "phpunit/php-code-coverage",
- "version": "10.1.2",
+ "version": "10.1.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "db1497ec8dd382e82c962f7abbe0320e4882ee4e"
+ "reference": "be1fe461fdc917de2a29a452ccf2657d325b443d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/db1497ec8dd382e82c962f7abbe0320e4882ee4e",
- "reference": "db1497ec8dd382e82c962f7abbe0320e4882ee4e",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/be1fe461fdc917de2a29a452ccf2657d325b443d",
+ "reference": "be1fe461fdc917de2a29a452ccf2657d325b443d",
"shasum": ""
},
"require": {
@@ -999,7 +999,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
- "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.2"
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.3"
},
"funding": [
{
@@ -1007,7 +1007,7 @@
"type": "github"
}
],
- "time": "2023-05-22T09:04:27+00:00"
+ "time": "2023-07-26T13:45:28+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -1253,16 +1253,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "10.1.3",
+ "version": "10.3.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "2379ebafc1737e71cdc84f402acb6b7f04198b9d"
+ "reference": "0dafb1175c366dd274eaa9a625e914451506bcd1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2379ebafc1737e71cdc84f402acb6b7f04198b9d",
- "reference": "2379ebafc1737e71cdc84f402acb6b7f04198b9d",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0dafb1175c366dd274eaa9a625e914451506bcd1",
+ "reference": "0dafb1175c366dd274eaa9a625e914451506bcd1",
"shasum": ""
},
"require": {
@@ -1287,7 +1287,7 @@
"sebastian/diff": "^5.0",
"sebastian/environment": "^6.0",
"sebastian/exporter": "^5.0",
- "sebastian/global-state": "^6.0",
+ "sebastian/global-state": "^6.0.1",
"sebastian/object-enumerator": "^5.0",
"sebastian/recursion-context": "^5.0",
"sebastian/type": "^4.0",
@@ -1302,7 +1302,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "10.1-dev"
+ "dev-main": "10.3-dev"
}
},
"autoload": {
@@ -1334,7 +1334,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/10.1.3"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.2"
},
"funding": [
{
@@ -1350,7 +1350,7 @@
"type": "tidelift"
}
],
- "time": "2023-05-11T05:16:22+00:00"
+ "time": "2023-08-15T05:34:23+00:00"
},
{
"name": "sebastian/cli-parser",
@@ -1521,16 +1521,16 @@
},
{
"name": "sebastian/comparator",
- "version": "5.0.0",
+ "version": "5.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "72f01e6586e0caf6af81297897bd112eb7e9627c"
+ "reference": "2db5010a484d53ebf536087a70b4a5423c102372"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/72f01e6586e0caf6af81297897bd112eb7e9627c",
- "reference": "72f01e6586e0caf6af81297897bd112eb7e9627c",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372",
+ "reference": "2db5010a484d53ebf536087a70b4a5423c102372",
"shasum": ""
},
"require": {
@@ -1541,7 +1541,7 @@
"sebastian/exporter": "^5.0"
},
"require-dev": {
- "phpunit/phpunit": "^10.0"
+ "phpunit/phpunit": "^10.3"
},
"type": "library",
"extra": {
@@ -1585,7 +1585,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
- "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.0"
+ "security": "https://github.com/sebastianbergmann/comparator/security/policy",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1"
},
"funding": [
{
@@ -1593,7 +1594,7 @@
"type": "github"
}
],
- "time": "2023-02-03T07:07:16+00:00"
+ "time": "2023-08-14T13:18:12+00:00"
},
{
"name": "sebastian/complexity",
@@ -1862,16 +1863,16 @@
},
{
"name": "sebastian/global-state",
- "version": "6.0.0",
+ "version": "6.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "aab257c712de87b90194febd52e4d184551c2d44"
+ "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/aab257c712de87b90194febd52e4d184551c2d44",
- "reference": "aab257c712de87b90194febd52e4d184551c2d44",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4",
+ "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4",
"shasum": ""
},
"require": {
@@ -1911,7 +1912,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
- "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.0"
+ "security": "https://github.com/sebastianbergmann/global-state/security/policy",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1"
},
"funding": [
{
@@ -1919,7 +1921,7 @@
"type": "github"
}
],
- "time": "2023-02-03T07:07:38+00:00"
+ "time": "2023-07-19T07:19:23+00:00"
},
{
"name": "sebastian/lines-of-code",
diff --git a/phpunit.xml b/phpunit.xml
index ef5e278..623a0bb 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -43,5 +43,9 @@
./tests/Usage/Session
+
+
+ ./tests/Usage/Random
+
diff --git a/src/AbstractModel.php b/src/AbstractModel.php
index 53951b9..5aa296c 100644
--- a/src/AbstractModel.php
+++ b/src/AbstractModel.php
@@ -30,6 +30,12 @@ abstract class AbstractModel implements \JsonSerializable
protected const FIELDS = [];
+ /**
+ * Stores dynamically assigned variables
+ * @var array
+ */
+ private array $_dyn = [];
+
/**
* AbstractModel constructor.
*
@@ -49,6 +55,16 @@ public function __construct(?array $data = [])
}
}
+ public function __set(string $field, $value): void
+ {
+ $this->_dyn[$field] = $value;
+ }
+
+ public function __get(string $field)
+ {
+ return $this->_dyn[$field] ?? null;
+ }
+
/**
* todo: this picks up non-public fields. externalize this at some point.
*
@@ -57,8 +73,19 @@ public function __construct(?array $data = [])
public function jsonSerialize(): array
{
$out = [];
+ // marshal fields
foreach ((array)$this as $field => $value) {
- $this->marshalField($out, $field, $value);
+ // marshal dynamically defined fields
+ // todo: this is crap.
+ if (substr($field, -4) === '_dyn') {
+ if ([] !== $value) {
+ foreach ($value as $k => $v) {
+ $this->marshalField($out, $k, $v);
+ }
+ }
+ } else {
+ $this->marshalField($out, $field, $value);
+ }
}
return $out;
}
diff --git a/src/Unmarshaller.php b/src/Unmarshaller.php
index 1202e55..76cd707 100644
--- a/src/Unmarshaller.php
+++ b/src/Unmarshaller.php
@@ -46,19 +46,22 @@ protected function unmarshalField(string $field, $value): void
// if the field isn't explicitly defined on the implementing class, just set it to whatever the incoming
// value is
$this->{$field} = $value;
- } /** @noinspection PhpStatementHasEmptyBodyInspection */ elseif (null === $value) {
- // if the value is null at this point, ignore and move on.
- // note: this is not checked prior to the property_exists call as if the field is not explicitly defined but
- // is seen with a null value, we still want to define it as null on the implementing type.
- } elseif (isset($this->{$field}) && is_scalar($this->{$field})) {
- // if the property has a scalar default value, unmarshal it as such.
- $this->unmarshalScalar($field, $value, false);
- } else {
- // if we fall down here, try to set the value as-is. if this barfs, it indicates we have a bug to be
- // squished.
- // todo: should this be an exception?
- $this->{$field} = $value;
+ } elseif (null !== $value) {
+ // at this point, value must be non-null to be operable
+ if (isset($this->{$field}) && is_scalar($this->{$field})) {
+ // if the property has a scalar default value, unmarshal it as such.
+ $this->unmarshalScalar($field, $value, false);
+ } else {
+ // if we fall down here, try to set the value as-is. if this barfs, it indicates we have a bug to be
+ // squished.
+ // todo: should this be an exception?
+ $this->{$field} = $value;
+ }
}
+
+ // if the value is null at this point, ignore and move on.
+ // note: this is not checked prior to the property_exists call as if the field is not explicitly defined but
+ // is seen with a null value, we still want to define it as null on the implementing type.
}
/**
@@ -333,7 +336,7 @@ private function unmarshalArray(string $field, $value, array $def): void
}
foreach ($value as $k => $v) {
- // todo: causes double-checking for null if value isn't null, not great...
+ // short circuit to prevent additional func call
if (null === $v) {
$this->{$field}[$k] = null;
} else {
@@ -343,6 +346,7 @@ private function unmarshalArray(string $field, $value, array $def): void
} else {
// in all other cases, just set as-is
foreach ($value as $k => $v) {
+ // short circuit to prevent additional func call
if (null === $v) {
$this->{$field}[$k] = null;
} else {
diff --git a/tests/Usage/Random/RandomWhateverTest.php b/tests/Usage/Random/RandomWhateverTest.php
new file mode 100644
index 0000000..965022b
--- /dev/null
+++ b/tests/Usage/Random/RandomWhateverTest.php
@@ -0,0 +1,46 @@
+assertIsObject($dec);
+
+ $kvp = new KVPair((array)$dec, false);
+
+ self::assertEquals($v, $kvp->{$k});
+ }
+}