Compare commits
36 Commits
fae4ee8929
...
c86a0cbcb1
| Author | SHA1 | Date | |
|---|---|---|---|
| c86a0cbcb1 | |||
| 8f61c4d2d5 | |||
| 319fcb6485 | |||
| 18478f9985 | |||
| 139b4df844 | |||
| a7ad86860d | |||
| 6ca83a7dd7 | |||
| 6a3e1f309e | |||
| 4d4999602c | |||
| 87d6af93b7 | |||
| 2b44d395f0 | |||
| 8ca85e894d | |||
| cc8482f309 | |||
| 14f25c9a44 | |||
| b6c3551d36 | |||
| a6e2a447e5 | |||
| 802849a60d | |||
| a3443b1e54 | |||
| cededf82c3 | |||
| 388e3fb8b8 | |||
| bc54ba5811 | |||
| 869f2e4fb4 | |||
| 6dadd13acf | |||
| 2d1ee97afe | |||
| 8432f5a823 | |||
| 30cfd06594 | |||
| 175981b5b2 | |||
| 0e8c91e82d | |||
| 2fc9cbe033 | |||
| 9deac1682e | |||
| 812a6680a8 | |||
| a7f57aecf7 | |||
| 9a234fb758 | |||
| 87940f8eaf | |||
| 8d716e3c72 | |||
| 4e1d6d65d0 |
+1
-1
@@ -11,7 +11,7 @@
|
|||||||
"mongodb/mongodb": "^2.1",
|
"mongodb/mongodb": "^2.1",
|
||||||
"php-di/php-di": "*",
|
"php-di/php-di": "*",
|
||||||
"phpseclib/phpseclib": "^3.0",
|
"phpseclib/phpseclib": "^3.0",
|
||||||
"symfony/console": "^7.0"
|
"symfony/console": "^8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^11.0"
|
"phpunit/phpunit": "^11.0"
|
||||||
|
|||||||
Generated
+33
-31
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "85ac161c93851c4863257009fc596644",
|
"content-hash": "95b9110e6c06e2d30edd0283b1bd630d",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "laravel/serializable-closure",
|
"name": "laravel/serializable-closure",
|
||||||
@@ -393,16 +393,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpseclib/phpseclib",
|
"name": "phpseclib/phpseclib",
|
||||||
"version": "3.0.52",
|
"version": "3.0.55",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpseclib/phpseclib.git",
|
"url": "https://github.com/phpseclib/phpseclib.git",
|
||||||
"reference": "2adaefc83df2ec548558307690f376dd7d4f4fce"
|
"reference": "db9744e6d47e742b1f974e965ad49bdd041105af"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/2adaefc83df2ec548558307690f376dd7d4f4fce",
|
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/db9744e6d47e742b1f974e965ad49bdd041105af",
|
||||||
"reference": "2adaefc83df2ec548558307690f376dd7d4f4fce",
|
"reference": "db9744e6d47e742b1f974e965ad49bdd041105af",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -483,7 +483,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/phpseclib/phpseclib/issues",
|
"issues": "https://github.com/phpseclib/phpseclib/issues",
|
||||||
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.52"
|
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.55"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -499,7 +499,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2026-04-27T07:02:15+00:00"
|
"time": "2026-06-14T23:24:10+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/container",
|
"name": "psr/container",
|
||||||
@@ -606,47 +606,49 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v7.4.11",
|
"version": "v8.1.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/console.git",
|
"url": "https://github.com/symfony/console.git",
|
||||||
"reference": "ed0107e43ab452aa77ae99e005b95e56b556e075"
|
"reference": "b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/console/zipball/ed0107e43ab452aa77ae99e005b95e56b556e075",
|
"url": "https://api.github.com/repos/symfony/console/zipball/b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d",
|
||||||
"reference": "ed0107e43ab452aa77ae99e005b95e56b556e075",
|
"reference": "b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.2",
|
"php": ">=8.4.1",
|
||||||
"symfony/deprecation-contracts": "^2.5|^3",
|
"symfony/deprecation-contracts": "^2.5|^3",
|
||||||
"symfony/polyfill-mbstring": "~1.0",
|
"symfony/polyfill-mbstring": "^1.0",
|
||||||
|
"symfony/polyfill-php85": "^1.32",
|
||||||
"symfony/service-contracts": "^2.5|^3",
|
"symfony/service-contracts": "^2.5|^3",
|
||||||
"symfony/string": "^7.2|^8.0"
|
"symfony/string": "^7.4.6|^8.0.6"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"symfony/dependency-injection": "<6.4",
|
"symfony/dependency-injection": "<8.1",
|
||||||
"symfony/dotenv": "<6.4",
|
"symfony/event-dispatcher": "<8.1"
|
||||||
"symfony/event-dispatcher": "<6.4",
|
|
||||||
"symfony/lock": "<6.4",
|
|
||||||
"symfony/process": "<6.4"
|
|
||||||
},
|
},
|
||||||
"provide": {
|
"provide": {
|
||||||
"psr/log-implementation": "1.0|2.0|3.0"
|
"psr/log-implementation": "1.0|2.0|3.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"psr/log": "^1|^2|^3",
|
"psr/log": "^1|^2|^3",
|
||||||
"symfony/config": "^6.4|^7.0|^8.0",
|
"symfony/config": "^7.4|^8.0",
|
||||||
"symfony/dependency-injection": "^6.4|^7.0|^8.0",
|
"symfony/dependency-injection": "^8.1",
|
||||||
"symfony/event-dispatcher": "^6.4|^7.0|^8.0",
|
"symfony/event-dispatcher": "^8.1",
|
||||||
"symfony/http-foundation": "^6.4|^7.0|^8.0",
|
"symfony/filesystem": "^7.4|^8.0",
|
||||||
"symfony/http-kernel": "^6.4|^7.0|^8.0",
|
"symfony/http-foundation": "^7.4|^8.0",
|
||||||
"symfony/lock": "^6.4|^7.0|^8.0",
|
"symfony/http-kernel": "^7.4|^8.0",
|
||||||
"symfony/messenger": "^6.4|^7.0|^8.0",
|
"symfony/lock": "^7.4|^8.0",
|
||||||
"symfony/process": "^6.4|^7.0|^8.0",
|
"symfony/messenger": "^7.4|^8.0",
|
||||||
"symfony/stopwatch": "^6.4|^7.0|^8.0",
|
"symfony/mime": "^7.4|^8.0",
|
||||||
"symfony/var-dumper": "^6.4|^7.0|^8.0"
|
"symfony/process": "^7.4|^8.0",
|
||||||
|
"symfony/stopwatch": "^7.4|^8.0",
|
||||||
|
"symfony/uid": "^7.4|^8.0",
|
||||||
|
"symfony/validator": "^7.4|^8.0",
|
||||||
|
"symfony/var-dumper": "^7.4|^8.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -680,7 +682,7 @@
|
|||||||
"terminal"
|
"terminal"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/console/tree/v7.4.11"
|
"source": "https://github.com/symfony/console/tree/v8.1.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -700,7 +702,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2026-05-13T12:04:42+00:00"
|
"time": "2026-06-16T12:55:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
|
|||||||
Generated
+143
-143
@@ -747,9 +747,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@oxc-project/types": {
|
"node_modules/@oxc-project/types": {
|
||||||
"version": "0.130.0",
|
"version": "0.132.0",
|
||||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.130.0.tgz",
|
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.132.0.tgz",
|
||||||
"integrity": "sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==",
|
"integrity": "sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/Boshen"
|
"url": "https://github.com/sponsors/Boshen"
|
||||||
@@ -1083,9 +1083,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-android-arm64": {
|
"node_modules/@rolldown/binding-android-arm64": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.2.tgz",
|
||||||
"integrity": "sha512-fJI3I0r3C3Oj/zdBCpaCmBRZYf07xpaq4yCfDDoSFm+beWNzbIl26puW8RraUdugoJw/95zerNOn6jasAhzSmg==",
|
"integrity": "sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1099,9 +1099,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-darwin-arm64": {
|
"node_modules/@rolldown/binding-darwin-arm64": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.2.tgz",
|
||||||
"integrity": "sha512-cKnAhWEsV7TPcA/5EAteDp6KcJZBQ2G+BqE7zayMMi7kMvwRsbv7WT9aOnn0WNl4SKEIf43vjS31iUPu80nzXg==",
|
"integrity": "sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1115,9 +1115,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-darwin-x64": {
|
"node_modules/@rolldown/binding-darwin-x64": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.2.tgz",
|
||||||
"integrity": "sha512-YKrVwQjIRBPo+5G/u03wGjbdy4q7pyzCe93DK9VJ7zkVmeg8LJ7GbgsiHWdR4xSoe4CAXRD7Bcjgbtr64bkXNg==",
|
"integrity": "sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1131,9 +1131,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-freebsd-x64": {
|
"node_modules/@rolldown/binding-freebsd-x64": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.2.tgz",
|
||||||
"integrity": "sha512-z/oBsREo46SsFqBwYtFe0kpJeBijAT48O/WXLI4suiCLBkr03RTtTJMCzSdDd2znlh8VJizL09XVkQgk8IZonw==",
|
"integrity": "sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1147,9 +1147,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.2.tgz",
|
||||||
"integrity": "sha512-ik8q7GM11zxvYxFc2PeDcT6TBvhCQMaUxfph/M5l9sKuTs/Sjg3L+Byw0F7w0ZVLBZmx30P+gG0ECzzN+MFcmQ==",
|
"integrity": "sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -1163,9 +1163,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.2.tgz",
|
||||||
"integrity": "sha512-QoSx2EkyrrdZ6kcyE8stqZ62t0Yra8Fs5ia9lOxJrh6TMQJK7gQKmscdTHf7pOXKREKrVwOtJcQG3qVSfc866A==",
|
"integrity": "sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1179,9 +1179,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.2.tgz",
|
||||||
"integrity": "sha512-uwNwFpwKeNiZawfAWBgg0VIztPTV3ihhh1vV334h9ivnNLorxnQMU6Fz8wG1Zb4Qh9LC1/MkcyT3YlDXG3Rsgg==",
|
"integrity": "sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1195,9 +1195,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
|
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.2.tgz",
|
||||||
"integrity": "sha512-zY1bul7OWr7DFBiJ++wofXvnr8B45ce3QsQUhKrIhXsygAh7bTkwyeM1bi1a2g5C/yC/N8TZyGDEoMfm/l9mpg==",
|
"integrity": "sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
@@ -1211,9 +1211,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-s390x-gnu": {
|
"node_modules/@rolldown/binding-linux-s390x-gnu": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.2.tgz",
|
||||||
"integrity": "sha512-0frlsT/f4Ft6I7SMESTKnF3cZsdicQn1dCMkF/jT9wDLE+gGoiQfv1nmT9e+s7s/fekvvy6tZM2jHvI2tkbJDQ==",
|
"integrity": "sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
@@ -1227,9 +1227,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.2.tgz",
|
||||||
"integrity": "sha512-XABVmGp9Tg0WspTVvwduTc4fpqy6JnAUrSQe6OuyqD/03nI7r0O9OWUkMIwFrjKAIqolvqoA4ZrJppgwE0Gxmw==",
|
"integrity": "sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1243,9 +1243,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-x64-musl": {
|
"node_modules/@rolldown/binding-linux-x64-musl": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.2.tgz",
|
||||||
"integrity": "sha512-bV4fzswuzVcKD90o/VM6QqKxnxlDq0g2BISDLNVmxrnhpv1DDbyPhCIjYfvzYLV+MvkKKnQt2Q6AO86SEBULUQ==",
|
"integrity": "sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1259,9 +1259,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-openharmony-arm64": {
|
"node_modules/@rolldown/binding-openharmony-arm64": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.2.tgz",
|
||||||
"integrity": "sha512-/Mh0Zhq3OP7fVs0kcQHZP6lZEthMGTaSf8UBQYSFEZDWGXXlEC+nJ6EqenaK2t4LBXMe3A+K/G2BVXXdtOr4PQ==",
|
"integrity": "sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1275,9 +1275,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-wasm32-wasi": {
|
"node_modules/@rolldown/binding-wasm32-wasi": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.2.tgz",
|
||||||
"integrity": "sha512-+1xc9X45l8ufsBAm6Gjvx2qDRIY9lTVt0cgWNcJ+1gdhXvkbxePA60yRTwSTuXL09CMhyJmjpV7E3NoyxbqFQQ==",
|
"integrity": "sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"wasm32"
|
"wasm32"
|
||||||
],
|
],
|
||||||
@@ -1293,9 +1293,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.2.tgz",
|
||||||
"integrity": "sha512-1D+UqZdfnuR+Jy1GgMJwi85bD40H21uNmOPRWQhw4oRSuolZ/B5rixZ45DK2KXOTCvmVCecauWgEhbw8bI7tOw==",
|
"integrity": "sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1309,9 +1309,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.2.tgz",
|
||||||
"integrity": "sha512-INAycaWuhlOK3wk4mRHGsdgwYWmd9cChdPdE9bwWmy6rn9VqVNYNFGhOdXrofXUxwHIncSiPNb8tNm8knDVIeQ==",
|
"integrity": "sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1688,14 +1688,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/coverage-v8": {
|
"node_modules/@vitest/coverage-v8": {
|
||||||
"version": "4.1.6",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.7.tgz",
|
||||||
"integrity": "sha512-36l628fQ/9a/8ihy97eOtEnvWQEdqULQOJtcaxtoNq0G1w3Mxd4szSahOaMM9/NGyZ+hyKcMtIW/WIxq0XQViQ==",
|
"integrity": "sha512-qsYPeXc5Q9dFLd1i8Ap+Bx8sQgcp+rFVQo4R0dDsWNBzl26ldVF1qOO+RL24K7FDrR6pA+50XedRLSoSG24bVQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bcoe/v8-coverage": "^1.0.2",
|
"@bcoe/v8-coverage": "^1.0.2",
|
||||||
"@vitest/utils": "4.1.6",
|
"@vitest/utils": "4.1.7",
|
||||||
"ast-v8-to-istanbul": "^1.0.0",
|
"ast-v8-to-istanbul": "^1.0.0",
|
||||||
"istanbul-lib-coverage": "^3.2.2",
|
"istanbul-lib-coverage": "^3.2.2",
|
||||||
"istanbul-lib-report": "^3.0.1",
|
"istanbul-lib-report": "^3.0.1",
|
||||||
@@ -1709,8 +1709,8 @@
|
|||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@vitest/browser": "4.1.6",
|
"@vitest/browser": "4.1.7",
|
||||||
"vitest": "4.1.6"
|
"vitest": "4.1.7"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"@vitest/browser": {
|
"@vitest/browser": {
|
||||||
@@ -1719,16 +1719,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/expect": {
|
"node_modules/@vitest/expect": {
|
||||||
"version": "4.1.6",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.7.tgz",
|
||||||
"integrity": "sha512-7EHDquPthALSV0jhhjgEW8FXaviMx7rSqu8W6oqCoAuOhKov814P99QDV1pxMA3QPv21YudvJngIhjrNI4opLg==",
|
"integrity": "sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standard-schema/spec": "^1.1.0",
|
"@standard-schema/spec": "^1.1.0",
|
||||||
"@types/chai": "^5.2.2",
|
"@types/chai": "^5.2.2",
|
||||||
"@vitest/spy": "4.1.6",
|
"@vitest/spy": "4.1.7",
|
||||||
"@vitest/utils": "4.1.6",
|
"@vitest/utils": "4.1.7",
|
||||||
"chai": "^6.2.2",
|
"chai": "^6.2.2",
|
||||||
"tinyrainbow": "^3.1.0"
|
"tinyrainbow": "^3.1.0"
|
||||||
},
|
},
|
||||||
@@ -1737,13 +1737,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/mocker": {
|
"node_modules/@vitest/mocker": {
|
||||||
"version": "4.1.6",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.7.tgz",
|
||||||
"integrity": "sha512-MCFc63czMjEInOlcY2cpQCvCN+KgbAn+60xu9cMgP4sKaLC5JNAKw7JH8QdAnoAC88hW1IiSNZ+GgVXlN1UcMQ==",
|
"integrity": "sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/spy": "4.1.6",
|
"@vitest/spy": "4.1.7",
|
||||||
"estree-walker": "^3.0.3",
|
"estree-walker": "^3.0.3",
|
||||||
"magic-string": "^0.30.21"
|
"magic-string": "^0.30.21"
|
||||||
},
|
},
|
||||||
@@ -1774,9 +1774,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/pretty-format": {
|
"node_modules/@vitest/pretty-format": {
|
||||||
"version": "4.1.6",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.7.tgz",
|
||||||
"integrity": "sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw==",
|
"integrity": "sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1787,13 +1787,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/runner": {
|
"node_modules/@vitest/runner": {
|
||||||
"version": "4.1.6",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.7.tgz",
|
||||||
"integrity": "sha512-nOPCmn2+yD0ZNmKdsXGv/UxMMWbMuKeD6GyYncNwdkYDxpQvrPSKYj2rWuDjC2Y4b6w6hjip5dBKFzEUuZe3vA==",
|
"integrity": "sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/utils": "4.1.6",
|
"@vitest/utils": "4.1.7",
|
||||||
"pathe": "^2.0.3"
|
"pathe": "^2.0.3"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
@@ -1801,14 +1801,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/snapshot": {
|
"node_modules/@vitest/snapshot": {
|
||||||
"version": "4.1.6",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.7.tgz",
|
||||||
"integrity": "sha512-YhsdE6xAVfTDmzjxL2ZDUvjj+ZsgyOKe+TdQzqkD72wIOmHka8NuGQ6NpTNZv9D2Z63fbwWKJPeVpEw4EQgYxw==",
|
"integrity": "sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/pretty-format": "4.1.6",
|
"@vitest/pretty-format": "4.1.7",
|
||||||
"@vitest/utils": "4.1.6",
|
"@vitest/utils": "4.1.7",
|
||||||
"magic-string": "^0.30.21",
|
"magic-string": "^0.30.21",
|
||||||
"pathe": "^2.0.3"
|
"pathe": "^2.0.3"
|
||||||
},
|
},
|
||||||
@@ -1817,9 +1817,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/spy": {
|
"node_modules/@vitest/spy": {
|
||||||
"version": "4.1.6",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.7.tgz",
|
||||||
"integrity": "sha512-JFKxMx6udhwKh/Ldo270e17QX710vgunMkuPAvXjHSvC6oqLWAHhVhjg/I71q0u0CBSErIODV1Kjv0FQNSWjdg==",
|
"integrity": "sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
@@ -1827,13 +1827,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/ui": {
|
"node_modules/@vitest/ui": {
|
||||||
"version": "4.1.6",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-4.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-4.1.7.tgz",
|
||||||
"integrity": "sha512-wiu5em68DfGv/2HFvI1Njr7JI2CHcBlQvereSzVG8my53PRxjTNOCsD9VOkRKrsJBDHmyuXvosxWZw7T91a2mw==",
|
"integrity": "sha512-TP6utB2yX6rsJNVRo2qAlsi48i1YwFTrLV2tnTtWqJaYX7m4lRCCLirZBjU6xC5m0RsPHr+L2+N+eIPhgEzFfw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/utils": "4.1.6",
|
"@vitest/utils": "4.1.7",
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
"flatted": "^3.4.2",
|
"flatted": "^3.4.2",
|
||||||
"pathe": "^2.0.3",
|
"pathe": "^2.0.3",
|
||||||
@@ -1845,17 +1845,17 @@
|
|||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vitest": "4.1.6"
|
"vitest": "4.1.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/utils": {
|
"node_modules/@vitest/utils": {
|
||||||
"version": "4.1.6",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.7.tgz",
|
||||||
"integrity": "sha512-FxIY+U81R3LGKCxaHHFRQ5+g6/iRgGLmeHWdp2Amj4ljQRrEIWHmZyDfDYBRZlpyqA7qKxtS9DD1dhk8RnRIVQ==",
|
"integrity": "sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/pretty-format": "4.1.6",
|
"@vitest/pretty-format": "4.1.7",
|
||||||
"convert-source-map": "^2.0.0",
|
"convert-source-map": "^2.0.0",
|
||||||
"tinyrainbow": "^3.1.0"
|
"tinyrainbow": "^3.1.0"
|
||||||
},
|
},
|
||||||
@@ -2084,9 +2084,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/test-utils": {
|
"node_modules/@vue/test-utils": {
|
||||||
"version": "2.4.10",
|
"version": "2.4.11",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.10.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.11.tgz",
|
||||||
"integrity": "sha512-SmoZ5EA1kYiAFs9NkYdiFFQF+cSnUwnvlYEbY+DogWQZUiqOm/Y29eSbc5T6yi75SgSF9863SBeXniIEoPajCA==",
|
"integrity": "sha512-GDqaqZsA6m2E5vNzej0aYiIb6BX8xV9pNSbbbXKOfEYwg7ZNblVX8suyqmUBThq8VIrgAJNxn+z72hVtUeiWHA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -2944,9 +2944,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dompurify": {
|
"node_modules/dompurify": {
|
||||||
"version": "3.4.3",
|
"version": "3.4.11",
|
||||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.11.tgz",
|
||||||
"integrity": "sha512-VVwJidIJcp1hpg2OMXML3ZVRPYSZiq4aX7qBh83BSIpOaRDqI+qxhXjjIWnpzkOXhmp0L81lnoME1mnCc9H48A==",
|
"integrity": "sha512-zhlUV12GsaRzMsf9q5M254YhA4+VuF0fG+QFqu6aYpoGlKtz+w8//jBcGVYBgQkR5GHjUomejY84AV+/uPbWdw==",
|
||||||
"license": "(MPL-2.0 OR Apache-2.0)",
|
"license": "(MPL-2.0 OR Apache-2.0)",
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@types/trusted-types": "^2.0.7"
|
"@types/trusted-types": "^2.0.7"
|
||||||
@@ -3206,9 +3206,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-vue": {
|
"node_modules/eslint-plugin-vue": {
|
||||||
"version": "10.9.1",
|
"version": "10.9.2",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.9.2.tgz",
|
||||||
"integrity": "sha512-cHB0Tf4Duvzwecwd/AqWzZvF/QszE13BhjVUpVXWCy9AeMR5GjkAjP3i85vqgLgOuTmkHR1OJ5oMeqLHtuw8zg==",
|
"integrity": "sha512-4g7ZP3pYcuqd7Zp0pzUKcos0W+RkjBz4EGdhJ92FcYk6v03Ti/GK5NwjgsjxHK+98eXDbHeK7VtX1az7/8doZA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -4900,9 +4900,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.5.14",
|
"version": "8.5.15",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
|
||||||
"integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==",
|
"integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -4919,7 +4919,7 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.11",
|
"nanoid": "^3.3.12",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
},
|
},
|
||||||
@@ -4951,9 +4951,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "3.8.3",
|
"version": "3.8.4",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.4.tgz",
|
||||||
"integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==",
|
"integrity": "sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -5076,12 +5076,12 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/rolldown": {
|
"node_modules/rolldown": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.2.tgz",
|
||||||
"integrity": "sha512-X0KQHljNnEkWNqqiz9zJrGunh1B0HgOxLXvnFpCOcadzcy5qohZ3tqMEUg00vncoRovXuK3ZqCT9KnnKzoInFQ==",
|
"integrity": "sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oxc-project/types": "=0.130.0",
|
"@oxc-project/types": "=0.132.0",
|
||||||
"@rolldown/pluginutils": "^1.0.0"
|
"@rolldown/pluginutils": "^1.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -5091,21 +5091,21 @@
|
|||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rolldown/binding-android-arm64": "1.0.1",
|
"@rolldown/binding-android-arm64": "1.0.2",
|
||||||
"@rolldown/binding-darwin-arm64": "1.0.1",
|
"@rolldown/binding-darwin-arm64": "1.0.2",
|
||||||
"@rolldown/binding-darwin-x64": "1.0.1",
|
"@rolldown/binding-darwin-x64": "1.0.2",
|
||||||
"@rolldown/binding-freebsd-x64": "1.0.1",
|
"@rolldown/binding-freebsd-x64": "1.0.2",
|
||||||
"@rolldown/binding-linux-arm-gnueabihf": "1.0.1",
|
"@rolldown/binding-linux-arm-gnueabihf": "1.0.2",
|
||||||
"@rolldown/binding-linux-arm64-gnu": "1.0.1",
|
"@rolldown/binding-linux-arm64-gnu": "1.0.2",
|
||||||
"@rolldown/binding-linux-arm64-musl": "1.0.1",
|
"@rolldown/binding-linux-arm64-musl": "1.0.2",
|
||||||
"@rolldown/binding-linux-ppc64-gnu": "1.0.1",
|
"@rolldown/binding-linux-ppc64-gnu": "1.0.2",
|
||||||
"@rolldown/binding-linux-s390x-gnu": "1.0.1",
|
"@rolldown/binding-linux-s390x-gnu": "1.0.2",
|
||||||
"@rolldown/binding-linux-x64-gnu": "1.0.1",
|
"@rolldown/binding-linux-x64-gnu": "1.0.2",
|
||||||
"@rolldown/binding-linux-x64-musl": "1.0.1",
|
"@rolldown/binding-linux-x64-musl": "1.0.2",
|
||||||
"@rolldown/binding-openharmony-arm64": "1.0.1",
|
"@rolldown/binding-openharmony-arm64": "1.0.2",
|
||||||
"@rolldown/binding-wasm32-wasi": "1.0.1",
|
"@rolldown/binding-wasm32-wasi": "1.0.2",
|
||||||
"@rolldown/binding-win32-arm64-msvc": "1.0.1",
|
"@rolldown/binding-win32-arm64-msvc": "1.0.2",
|
||||||
"@rolldown/binding-win32-x64-msvc": "1.0.1"
|
"@rolldown/binding-win32-x64-msvc": "1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass": {
|
"node_modules/sass": {
|
||||||
@@ -6050,15 +6050,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "8.0.13",
|
"version": "8.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.14.tgz",
|
||||||
"integrity": "sha512-MFtjBYgzmSxmgA4RAfjIyXWpGe1oALnjgUTzzV7QLx/TKxCzjtMH6Fd9/eVK+5Fg1qNoz5VAwsmMs/NofrmJvw==",
|
"integrity": "sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lightningcss": "^1.32.0",
|
"lightningcss": "^1.32.0",
|
||||||
"picomatch": "^4.0.4",
|
"picomatch": "^4.0.4",
|
||||||
"postcss": "^8.5.14",
|
"postcss": "^8.5.15",
|
||||||
"rolldown": "1.0.1",
|
"rolldown": "1.0.2",
|
||||||
"tinyglobby": "^0.2.16"
|
"tinyglobby": "^0.2.16"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -6233,19 +6233,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vitest": {
|
"node_modules/vitest": {
|
||||||
"version": "4.1.6",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.7.tgz",
|
||||||
"integrity": "sha512-6lvjbS3p9b4CrdCmguzbh2/4uoXhGE2q71R4OX5sqF9R1bo9Xd6fGrMAfvp5wnCzlBnFVdCOp6onuTQVbo8iUQ==",
|
"integrity": "sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/expect": "4.1.6",
|
"@vitest/expect": "4.1.7",
|
||||||
"@vitest/mocker": "4.1.6",
|
"@vitest/mocker": "4.1.7",
|
||||||
"@vitest/pretty-format": "4.1.6",
|
"@vitest/pretty-format": "4.1.7",
|
||||||
"@vitest/runner": "4.1.6",
|
"@vitest/runner": "4.1.7",
|
||||||
"@vitest/snapshot": "4.1.6",
|
"@vitest/snapshot": "4.1.7",
|
||||||
"@vitest/spy": "4.1.6",
|
"@vitest/spy": "4.1.7",
|
||||||
"@vitest/utils": "4.1.6",
|
"@vitest/utils": "4.1.7",
|
||||||
"es-module-lexer": "^2.0.0",
|
"es-module-lexer": "^2.0.0",
|
||||||
"expect-type": "^1.3.0",
|
"expect-type": "^1.3.0",
|
||||||
"magic-string": "^0.30.21",
|
"magic-string": "^0.30.21",
|
||||||
@@ -6273,12 +6273,12 @@
|
|||||||
"@edge-runtime/vm": "*",
|
"@edge-runtime/vm": "*",
|
||||||
"@opentelemetry/api": "^1.9.0",
|
"@opentelemetry/api": "^1.9.0",
|
||||||
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
|
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
|
||||||
"@vitest/browser-playwright": "4.1.6",
|
"@vitest/browser-playwright": "4.1.7",
|
||||||
"@vitest/browser-preview": "4.1.6",
|
"@vitest/browser-preview": "4.1.7",
|
||||||
"@vitest/browser-webdriverio": "4.1.6",
|
"@vitest/browser-webdriverio": "4.1.7",
|
||||||
"@vitest/coverage-istanbul": "4.1.6",
|
"@vitest/coverage-istanbul": "4.1.7",
|
||||||
"@vitest/coverage-v8": "4.1.6",
|
"@vitest/coverage-v8": "4.1.7",
|
||||||
"@vitest/ui": "4.1.6",
|
"@vitest/ui": "4.1.7",
|
||||||
"happy-dom": "*",
|
"happy-dom": "*",
|
||||||
"jsdom": "*",
|
"jsdom": "*",
|
||||||
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ abstract class CollectionMutableAbstract extends NodeMutableAbstract implements
|
|||||||
|
|
||||||
// Copy all property values
|
// Copy all property values
|
||||||
$this->properties->setLabel($value->getLabel());
|
$this->properties->setLabel($value->getLabel());
|
||||||
|
$this->properties->setDescription($value->getDescription());
|
||||||
|
$this->properties->setRank($value->getRank());
|
||||||
|
$this->properties->setVisibility($value->getVisibility());
|
||||||
|
$this->properties->setColor($value->getColor());
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,57 +20,53 @@ use KTXF\Resource\Provider\Node\NodePropertiesBaseAbstract;
|
|||||||
*/
|
*/
|
||||||
abstract class CollectionPropertiesBaseAbstract extends NodePropertiesBaseAbstract implements CollectionPropertiesBaseInterface {
|
abstract class CollectionPropertiesBaseAbstract extends NodePropertiesBaseAbstract implements CollectionPropertiesBaseInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = CollectionPropertiesBaseInterface::JSON_TYPE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function content(): CollectionContent {
|
public function content(): array {
|
||||||
$content = $this->data[self::JSON_PROPERTY_CONTENTS] ?? null;
|
$content = $this->data[self::PROPERTY_CONTENT] ?? null;
|
||||||
if ($content instanceof CollectionContent) {
|
if (is_array($content)) {
|
||||||
return $content;
|
return array_filter(array_map(function ($item) {
|
||||||
|
return $item instanceof CollectionContent ? $item : CollectionContent::tryFrom($item);
|
||||||
|
}, $content));
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_string($content)) {
|
|
||||||
return CollectionContent::tryFrom($content) ?? CollectionContent::Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CollectionContent::Event;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getLabel(): string {
|
public function getLabel(): string {
|
||||||
return $this->data[self::JSON_PROPERTY_LABEL] ?? '';
|
return $this->data[self::PROPERTY_LABEL] ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getDescription(): ?string {
|
public function getDescription(): ?string {
|
||||||
return $this->data[self::JSON_PROPERTY_DESCRIPTION] ?? null;
|
return $this->data[self::PROPERTY_DESCRIPTION] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getPriority(): ?int {
|
public function getRank(): ?int {
|
||||||
return $this->data[self::JSON_PROPERTY_PRIORITY] ?? null;
|
return $this->data[self::PROPERTY_RANK] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getVisibility(): ?bool {
|
public function getVisibility(): ?bool {
|
||||||
return $this->data[self::JSON_PROPERTY_VISIBILITY] ?? null;
|
return $this->data[self::PROPERTY_VISIBILITY] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getColor(): ?string {
|
public function getColor(): ?string {
|
||||||
return $this->data[self::JSON_PROPERTY_COLOR] ?? null;
|
return $this->data[self::PROPERTY_COLOR] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,15 +14,22 @@ use KTXF\Resource\Provider\Node\NodePropertiesBaseInterface;
|
|||||||
interface CollectionPropertiesBaseInterface extends NodePropertiesBaseInterface {
|
interface CollectionPropertiesBaseInterface extends NodePropertiesBaseInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = 'chrono:collection';
|
public const JSON_TYPE = 'chrono:collection';
|
||||||
public const JSON_PROPERTY_CONTENTS = 'content';
|
public const PROPERTY_CONTENT = 'content';
|
||||||
|
|
||||||
public const JSON_PROPERTY_LABEL = 'label';
|
public const PROPERTY_LABEL = 'label';
|
||||||
public const JSON_PROPERTY_DESCRIPTION = 'description';
|
public const PROPERTY_DESCRIPTION = 'description';
|
||||||
public const JSON_PROPERTY_PRIORITY = 'priority';
|
public const PROPERTY_RANK = 'rank';
|
||||||
public const JSON_PROPERTY_VISIBILITY = 'visibility';
|
public const PROPERTY_VISIBILITY = 'visibility';
|
||||||
public const JSON_PROPERTY_COLOR = 'color';
|
public const PROPERTY_COLOR = 'color';
|
||||||
|
|
||||||
public function content(): CollectionContent;
|
/**
|
||||||
|
* Gets the content type of this collection
|
||||||
|
*
|
||||||
|
* @since 2025.05.01
|
||||||
|
*
|
||||||
|
* @return CollectionContent[] Returns an array of content types, a single content type, or null if not set
|
||||||
|
*/
|
||||||
|
public function content(): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the human friendly name of this collection (e.g. Personal Calendar)
|
* Gets the human friendly name of this collection (e.g. Personal Calendar)
|
||||||
@@ -39,11 +46,11 @@ interface CollectionPropertiesBaseInterface extends NodePropertiesBaseInterface
|
|||||||
public function getDescription(): ?string;
|
public function getDescription(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the priority of this collection
|
* Gets the rank of this collection
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
public function getPriority(): ?int;
|
public function getRank(): ?int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the visibility of this collection
|
* Gets the visibility of this collection
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ abstract class CollectionPropertiesMutableAbstract extends CollectionPropertiesB
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setLabel(string $value): static {
|
public function setLabel(string $value): static {
|
||||||
$this->data[self::JSON_PROPERTY_LABEL] = $value;
|
$this->data[self::PROPERTY_LABEL] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,15 +41,15 @@ abstract class CollectionPropertiesMutableAbstract extends CollectionPropertiesB
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setDescription(?string $value): static {
|
public function setDescription(?string $value): static {
|
||||||
$this->data[self::JSON_PROPERTY_DESCRIPTION] = $value;
|
$this->data[self::PROPERTY_DESCRIPTION] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setPriority(?int $value): static {
|
public function setRank(?int $value): static {
|
||||||
$this->data[self::JSON_PROPERTY_PRIORITY] = $value;
|
$this->data[self::PROPERTY_RANK] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ abstract class CollectionPropertiesMutableAbstract extends CollectionPropertiesB
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setVisibility(?bool $value): static {
|
public function setVisibility(?bool $value): static {
|
||||||
$this->data[self::JSON_PROPERTY_VISIBILITY] = $value;
|
$this->data[self::PROPERTY_VISIBILITY] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ abstract class CollectionPropertiesMutableAbstract extends CollectionPropertiesB
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setColor(?string $value): static {
|
public function setColor(?string $value): static {
|
||||||
$this->data[self::JSON_PROPERTY_COLOR] = $value;
|
$this->data[self::PROPERTY_COLOR] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,11 +30,11 @@ interface CollectionPropertiesMutableInterface extends CollectionPropertiesBaseI
|
|||||||
public function setDescription(?string $value): static;
|
public function setDescription(?string $value): static;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the priority of this collection
|
* Sets the rank of this collection
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
public function setPriority(?int $value): static;
|
public function setRank(?int $value): static;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the visibility of this collection
|
* Sets the visibility of this collection
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace KTXF\Chrono\Entity;
|
namespace KTXF\Chrono\Entity;
|
||||||
|
|
||||||
|
use KTXF\Resource\Identifier\EntityIdentifier;
|
||||||
use KTXF\Resource\Provider\Node\NodeBaseAbstract;
|
use KTXF\Resource\Provider\Node\NodeBaseAbstract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,7 +21,12 @@ use KTXF\Resource\Provider\Node\NodeBaseAbstract;
|
|||||||
*/
|
*/
|
||||||
abstract class EntityBaseAbstract extends NodeBaseAbstract implements EntityBaseInterface {
|
abstract class EntityBaseAbstract extends NodeBaseAbstract implements EntityBaseInterface {
|
||||||
|
|
||||||
protected EntityPropertiesBaseAbstract $properties;
|
protected string $type = 'chrono:entity';
|
||||||
|
protected EntityPropertiesBaseInterface $properties;
|
||||||
|
|
||||||
|
protected function nodeIdentifier(): EntityIdentifier {
|
||||||
|
return new EntityIdentifier($this->data[static::PROPERTY_PROVIDER], $this->data[static::PROPERTY_SERVICE], $this->data[static::PROPERTY_COLLECTION], $this->data[static::PROPERTY_IDENTIFIER]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ use KTXF\Resource\Provider\Node\NodeBaseInterface;
|
|||||||
|
|
||||||
interface EntityBaseInterface extends NodeBaseInterface {
|
interface EntityBaseInterface extends NodeBaseInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = 'chrono.entity';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the entity properties
|
* Gets the entity properties
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace KTXF\Chrono\Entity;
|
namespace KTXF\Chrono\Entity;
|
||||||
|
|
||||||
|
use KTXF\Resource\Identifier\EntityIdentifier;
|
||||||
use KTXF\Resource\Provider\Node\NodeMutableAbstract;
|
use KTXF\Resource\Provider\Node\NodeMutableAbstract;
|
||||||
use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface;
|
use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface;
|
||||||
|
|
||||||
@@ -21,9 +22,12 @@ use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface;
|
|||||||
*/
|
*/
|
||||||
abstract class EntityMutableAbstract extends NodeMutableAbstract implements EntityMutableInterface {
|
abstract class EntityMutableAbstract extends NodeMutableAbstract implements EntityMutableInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = EntityMutableInterface::JSON_TYPE;
|
protected string $type = 'chrono:entity';
|
||||||
|
protected EntityPropertiesMutableInterface $properties;
|
||||||
|
|
||||||
protected EntityPropertiesMutableAbstract $properties;
|
protected function nodeIdentifier(): EntityIdentifier {
|
||||||
|
return new EntityIdentifier($this->data[static::PROPERTY_PROVIDER], $this->data[static::PROPERTY_SERVICE], (string) $this->data[static::PROPERTY_COLLECTION], (string) $this->data[static::PROPERTY_IDENTIFIER]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
@@ -40,7 +44,7 @@ abstract class EntityMutableAbstract extends NodeMutableAbstract implements Enti
|
|||||||
throw new \InvalidArgumentException('Properties must implement EntityPropertiesMutableInterface');
|
throw new \InvalidArgumentException('Properties must implement EntityPropertiesMutableInterface');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->properties->setDataRaw($value->getDataRaw());
|
$this->properties = $value;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ use KTXF\Resource\Provider\Node\NodeMutableInterface;
|
|||||||
*/
|
*/
|
||||||
interface EntityMutableInterface extends EntityBaseInterface, NodeMutableInterface {
|
interface EntityMutableInterface extends EntityBaseInterface, NodeMutableInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = EntityBaseInterface::JSON_TYPE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the entity properties (mutable)
|
* Gets the entity properties (mutable)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ use KTXF\Resource\Provider\Node\NodePropertiesBaseAbstract;
|
|||||||
|
|
||||||
abstract class EntityPropertiesBaseAbstract extends NodePropertiesBaseAbstract implements EntityPropertiesBaseInterface {
|
abstract class EntityPropertiesBaseAbstract extends NodePropertiesBaseAbstract implements EntityPropertiesBaseInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = EntityPropertiesBaseInterface::JSON_TYPE;
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public function getDataRaw(): array|string|null {
|
public function getDataRaw(): array|string|null {
|
||||||
return $this->data[self::JSON_PROPERTY_DATA] ?? null;
|
return $this->data[self::PROPERTY_DATA] ?? null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use KTXF\Resource\Provider\Node\NodePropertiesBaseInterface;
|
|||||||
interface EntityPropertiesBaseInterface extends NodePropertiesBaseInterface {
|
interface EntityPropertiesBaseInterface extends NodePropertiesBaseInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = 'chrono:entity';
|
public const JSON_TYPE = 'chrono:entity';
|
||||||
public const JSON_PROPERTY_DATA = 'data';
|
public const PROPERTY_DATA = 'data';
|
||||||
|
|
||||||
public function getDataRaw(): array|string|null;
|
public function getDataRaw(): array|string|null;
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ abstract class EntityPropertiesMutableAbstract extends EntityPropertiesBaseAbstr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function setDataRaw(array|string|null $value): static {
|
public function setDataRaw(array|string|null $value): static {
|
||||||
$this->data[self::JSON_PROPERTY_DATA] = $value;
|
$this->data[self::PROPERTY_DATA] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface;
|
|||||||
|
|
||||||
interface EntityPropertiesMutableInterface extends EntityPropertiesBaseInterface, NodePropertiesMutableInterface {
|
interface EntityPropertiesMutableInterface extends EntityPropertiesBaseInterface, NodePropertiesMutableInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = EntityPropertiesBaseInterface::JSON_TYPE;
|
|
||||||
|
|
||||||
public function setDataRaw(array|string|null $value): static;
|
public function setDataRaw(array|string|null $value): static;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,12 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity;
|
||||||
|
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
|
use KTXF\Chrono\Entity\Property\EventCommonObject;
|
||||||
|
use KTXF\Chrono\Entity\Property\EventMutationCollection;
|
||||||
|
use KTXF\Chrono\Entity\Property\EventOccurrenceObject;
|
||||||
|
|
||||||
class EventObject extends EventCommonObject {
|
class EventObject extends EventCommonObject {
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace KTXF\Chrono\Entity;
|
||||||
|
|
||||||
|
use DateTimeInterface;
|
||||||
|
use KTXF\Chrono\Entity\Property\AttachmentCollection;
|
||||||
|
use KTXF\Chrono\Entity\Property\JournalStatusTypes;
|
||||||
|
use KTXF\Chrono\Entity\Property\JournalVisibilityTypes;
|
||||||
|
use KTXF\Chrono\Entity\Property\TagCollection;
|
||||||
|
use KTXF\Json\JsonSerializableObject;
|
||||||
|
|
||||||
|
class JournalObject extends JsonSerializableObject {
|
||||||
|
public string $type = 'journal';
|
||||||
|
public int $version = 1;
|
||||||
|
public ?string $urid = null;
|
||||||
|
public ?DateTimeInterface $created = null;
|
||||||
|
public ?DateTimeInterface $modified = null;
|
||||||
|
public ?string $label = null;
|
||||||
|
public ?string $description = null;
|
||||||
|
public TagCollection $tags;
|
||||||
|
public ?string $content = null;
|
||||||
|
public ?DateTimeInterface $startsOn = null;
|
||||||
|
public ?DateTimeInterface $endsOn = null;
|
||||||
|
public ?JournalStatusTypes $status = null;
|
||||||
|
public ?JournalVisibilityTypes $visibility = null;
|
||||||
|
public AttachmentCollection $attachments;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->tags = new TagCollection();
|
||||||
|
$this->attachments = new AttachmentCollection();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
|
use KTXF\Json\JsonSerializableCollection;
|
||||||
|
|
||||||
|
class AttachmentCollection extends JsonSerializableCollection {
|
||||||
|
public function __construct(array $data = []) {
|
||||||
|
parent::__construct($data, AttachmentObject::class, 'string');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
|
use KTXF\Json\JsonSerializableObject;
|
||||||
|
|
||||||
|
class AttachmentObject extends JsonSerializableObject {
|
||||||
|
public ?string $uri = null;
|
||||||
|
public ?string $type = null;
|
||||||
|
public ?string $label = null;
|
||||||
|
public ?int $priority = null;
|
||||||
|
}
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
enum EventAvailabilityTypes: string {
|
enum EventAvailabilityTypes: string {
|
||||||
case Free = 'free';
|
case Free = 'free';
|
||||||
+3
-3
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use DateInterval;
|
use DateInterval;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
@@ -33,7 +33,7 @@ class EventCommonObject extends JsonSerializableObject {
|
|||||||
public EventSensitivityTypes|null $sensitivity = null;
|
public EventSensitivityTypes|null $sensitivity = null;
|
||||||
public int|null $priority = null;
|
public int|null $priority = null;
|
||||||
public string|null $color = null;
|
public string|null $color = null;
|
||||||
public EventTagCollection $tags;
|
public TagCollection $tags;
|
||||||
public EventOrganizerObject $organizer;
|
public EventOrganizerObject $organizer;
|
||||||
public EventParticipantCollection $participants;
|
public EventParticipantCollection $participants;
|
||||||
public EventNotificationCollection $notifications;
|
public EventNotificationCollection $notifications;
|
||||||
@@ -44,7 +44,7 @@ class EventCommonObject extends JsonSerializableObject {
|
|||||||
$this->locationsVirtual = new EventLocationVirtualCollection();
|
$this->locationsVirtual = new EventLocationVirtualCollection();
|
||||||
$this->notifications = new EventNotificationCollection();
|
$this->notifications = new EventNotificationCollection();
|
||||||
$this->organizer = new EventOrganizerObject();
|
$this->organizer = new EventOrganizerObject();
|
||||||
$this->tags = new EventTagCollection();
|
$this->tags = new TagCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use KTXF\Json\JsonSerializableCollection;
|
use KTXF\Json\JsonSerializableCollection;
|
||||||
|
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use KTXF\Json\JsonSerializableObject;
|
use KTXF\Json\JsonSerializableObject;
|
||||||
|
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use KTXF\Json\JsonSerializableCollection;
|
use KTXF\Json\JsonSerializableCollection;
|
||||||
|
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use KTXF\Json\JsonSerializableObject;
|
use KTXF\Json\JsonSerializableObject;
|
||||||
|
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use KTXF\Json\JsonSerializableCollection;
|
use KTXF\Json\JsonSerializableCollection;
|
||||||
|
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
enum EventNotificationAnchorTypes: string {
|
enum EventNotificationAnchorTypes: string {
|
||||||
case Start = 'start';
|
case Start = 'start';
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use KTXF\Json\JsonSerializableCollection;
|
use KTXF\Json\JsonSerializableCollection;
|
||||||
|
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use DateInterval;
|
use DateInterval;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
enum EventNotificationPatterns: string {
|
enum EventNotificationPatterns: string {
|
||||||
case Absolute = 'absolute';
|
case Absolute = 'absolute';
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
enum EventNotificationTypes: string {
|
enum EventNotificationTypes: string {
|
||||||
case Visual = 'visual';
|
case Visual = 'visual';
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
enum EventOccurrencePatternTypes: string {
|
enum EventOccurrencePatternTypes: string {
|
||||||
case Absolute = 'absolute';
|
case Absolute = 'absolute';
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
enum EventOccurrencePrecisionTypes: string {
|
enum EventOccurrencePrecisionTypes: string {
|
||||||
case Yearly = 'yearly';
|
case Yearly = 'yearly';
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use KTXF\Json\JsonSerializableObject;
|
use KTXF\Json\JsonSerializableObject;
|
||||||
|
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use KTXF\Json\JsonSerializableCollection;
|
use KTXF\Json\JsonSerializableCollection;
|
||||||
|
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use KTXF\Json\JsonSerializableObject;
|
use KTXF\Json\JsonSerializableObject;
|
||||||
|
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
enum EventParticipantRealm: string {
|
enum EventParticipantRealm: string {
|
||||||
case Internal = 'I';
|
case Internal = 'I';
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
use KTXF\Json\JsonSerializableCollection;
|
use KTXF\Json\JsonSerializableCollection;
|
||||||
|
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
enum EventParticipantRoleTypes: string {
|
enum EventParticipantRoleTypes: string {
|
||||||
case Owner = 'owner';
|
case Owner = 'owner';
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
enum EventParticipantStatusTypes: string {
|
enum EventParticipantStatusTypes: string {
|
||||||
case None = 'none';
|
case None = 'none';
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
enum EventParticipantTypes: string {
|
enum EventParticipantTypes: string {
|
||||||
case Unknown = 'unknown';
|
case Unknown = 'unknown';
|
||||||
+1
-1
@@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace KTXF\Chrono\Event;
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
enum EventSensitivityTypes: string {
|
enum EventSensitivityTypes: string {
|
||||||
case Public = 'public';
|
case Public = 'public';
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
|
enum JournalStatusTypes: string {
|
||||||
|
case Draft = 'draft';
|
||||||
|
case Final = 'final';
|
||||||
|
case Cancelled = 'cancelled';
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
|
enum JournalVisibilityTypes: string {
|
||||||
|
case Public = 'public';
|
||||||
|
case Private = 'private';
|
||||||
|
case Confidential = 'confidential';
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
|
use KTXF\Json\JsonSerializableCollection;
|
||||||
|
|
||||||
|
class TagCollection extends JsonSerializableCollection {
|
||||||
|
public function __construct(array $data = []) {
|
||||||
|
parent::__construct($data, 'string');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
|
use DateTimeInterface;
|
||||||
|
use KTXF\Json\JsonSerializableObject;
|
||||||
|
|
||||||
|
class TaskRecurrenceObject extends JsonSerializableObject {
|
||||||
|
public ?string $frequency = null;
|
||||||
|
public ?int $interval = null;
|
||||||
|
public ?int $count = null;
|
||||||
|
public ?DateTimeInterface $until = null;
|
||||||
|
public array $byDay = [];
|
||||||
|
public array $byMonthDay = [];
|
||||||
|
public array $byMonth = [];
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
|
enum TaskStatusTypes: string {
|
||||||
|
case NeedsAction = 'needs-action';
|
||||||
|
case InProcess = 'in-process';
|
||||||
|
case Completed = 'completed';
|
||||||
|
case Cancelled = 'cancelled';
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
|
use KTXF\Json\JsonSerializableCollection;
|
||||||
|
|
||||||
|
class TaskSubtaskCollection extends JsonSerializableCollection {
|
||||||
|
public function __construct(array $data = []) {
|
||||||
|
parent::__construct($data, TaskSubtaskObject::class, 'string');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace KTXF\Chrono\Entity\Property;
|
||||||
|
|
||||||
|
use KTXF\Json\JsonSerializableObject;
|
||||||
|
|
||||||
|
class TaskSubtaskObject extends JsonSerializableObject {
|
||||||
|
public ?string $label = null;
|
||||||
|
public bool $completed = false;
|
||||||
|
public ?int $priority = null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace KTXF\Chrono\Entity;
|
||||||
|
|
||||||
|
use DateTimeInterface;
|
||||||
|
use KTXF\Chrono\Entity\Property\AttachmentCollection;
|
||||||
|
use KTXF\Chrono\Entity\Property\TagCollection;
|
||||||
|
use KTXF\Chrono\Entity\Property\TaskRecurrenceObject;
|
||||||
|
use KTXF\Chrono\Entity\Property\TaskStatusTypes;
|
||||||
|
use KTXF\Chrono\Entity\Property\TaskSubtaskCollection;
|
||||||
|
use KTXF\Json\JsonSerializableObject;
|
||||||
|
|
||||||
|
class TaskObject extends JsonSerializableObject {
|
||||||
|
public string $type = 'task';
|
||||||
|
public int $version = 1;
|
||||||
|
public ?string $urid = null;
|
||||||
|
public ?DateTimeInterface $created = null;
|
||||||
|
public ?DateTimeInterface $modified = null;
|
||||||
|
public ?string $label = null;
|
||||||
|
public ?string $description = null;
|
||||||
|
public TagCollection $tags;
|
||||||
|
public ?DateTimeInterface $startsOn = null;
|
||||||
|
public ?DateTimeInterface $dueOn = null;
|
||||||
|
public ?DateTimeInterface $completedOn = null;
|
||||||
|
public ?TaskStatusTypes $status = null;
|
||||||
|
public ?int $priority = null;
|
||||||
|
public ?int $progress = null;
|
||||||
|
public ?string $color = null;
|
||||||
|
public ?TaskRecurrenceObject $recurrence = null;
|
||||||
|
public TaskSubtaskCollection $subtasks;
|
||||||
|
public AttachmentCollection $attachments;
|
||||||
|
public ?string $notes = null;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->tags = new TagCollection();
|
||||||
|
$this->subtasks = new TaskSubtaskCollection();
|
||||||
|
$this->attachments = new AttachmentCollection();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ namespace KTXF\Chrono\Provider;
|
|||||||
use KTXF\Resource\Provider\ResourceProviderBaseInterface;
|
use KTXF\Resource\Provider\ResourceProviderBaseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chrono Provider Base Interface
|
* Provider Base Interface
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -12,11 +12,9 @@ namespace KTXF\Chrono\Provider;
|
|||||||
use KTXF\Resource\Provider\ResourceProviderServiceMutateInterface;
|
use KTXF\Resource\Provider\ResourceProviderServiceMutateInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chrono Provider Service Mutate Interface
|
* Provider Service Mutate Interface
|
||||||
*
|
*
|
||||||
* Optional interface for providers that support service CRUD operations.
|
* Optional interface for providers that support service CRUD operations
|
||||||
*
|
|
||||||
* Implementations return ServiceMutableInterface instances (which extend ResourceServiceMutateInterface).
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
@@ -25,11 +23,8 @@ use KTXF\Resource\Provider\ResourceProviderServiceMutateInterface;
|
|||||||
* @method string serviceModify(string $tenantId, ?string $userId, ServiceMutableInterface $service) Modify a chrono service configuration
|
* @method string serviceModify(string $tenantId, ?string $userId, ServiceMutableInterface $service) Modify a chrono service configuration
|
||||||
* @method bool serviceDestroy(string $tenantId, ?string $userId, ServiceMutableInterface $service) Delete a chrono service configuration
|
* @method bool serviceDestroy(string $tenantId, ?string $userId, ServiceMutableInterface $service) Delete a chrono service configuration
|
||||||
*/
|
*/
|
||||||
interface ProviderServiceMutateInterface extends ProviderBaseInterface, ResourceProviderServiceMutateInterface {
|
interface ProviderServiceMutateInterface extends ResourceProviderServiceMutateInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = ProviderBaseInterface::JSON_TYPE;
|
// Methods inherited from ResourceProviderServiceMutateInterface
|
||||||
|
|
||||||
// Methods inherited from ResourceProviderServiceMutateInterface
|
|
||||||
// Implementations should return/accept ServiceMutableInterface instances
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,36 +10,27 @@ declare(strict_types=1);
|
|||||||
namespace KTXF\Chrono\Provider;
|
namespace KTXF\Chrono\Provider;
|
||||||
|
|
||||||
use KTXF\Chrono\Service\ServiceBaseInterface;
|
use KTXF\Chrono\Service\ServiceBaseInterface;
|
||||||
|
use KTXF\Chrono\Service\ServiceMutableInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chrono Provider Service Test Interface
|
* Provider Service Test Interface
|
||||||
*
|
*
|
||||||
* Optional interface for chrono providers that support testing service connections.
|
* Optional interface for providers that support testing service connections
|
||||||
* Providers implementing this interface can validate connection parameters,
|
|
||||||
* test authentication, and verify service availability before creating a
|
|
||||||
* persistent service configuration.
|
|
||||||
*
|
|
||||||
* Supports two testing modes:
|
|
||||||
* 1. Testing an existing service (validate current configuration)
|
|
||||||
* 2. Testing a fresh configuration (validate before saving)
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
interface ProviderServiceTestInterface extends ProviderBaseInterface {
|
interface ProviderServiceTestInterface {
|
||||||
|
|
||||||
|
public const CAPABILITY_SERVICE_TEST = 'ServiceTest';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test a service connection
|
* Test a service connection
|
||||||
*
|
*
|
||||||
* Tests connectivity, authentication, and capabilities of a service.
|
* Tests connectivity, authentication, and capabilities of a service
|
||||||
*
|
|
||||||
* For new services: use serviceFresh() to create a service, configure it with
|
|
||||||
* setters, then pass it to this method for testing before persisting.
|
|
||||||
*
|
|
||||||
* For existing services: fetch the service and pass it directly.
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param ServiceBaseInterface $service Service to test (can be fresh/unsaved or existing)
|
* @param ServiceBaseInterface|ServiceMutableInterface $service Service to test (can be fresh/unsaved or existing)
|
||||||
* @param array $options Provider-specific test options:
|
* @param array $options Provider-specific test options:
|
||||||
* - 'timeout' => int (seconds, default: 10)
|
* - 'timeout' => int (seconds, default: 10)
|
||||||
* - 'verify_ssl' => bool (default: true)
|
* - 'verify_ssl' => bool (default: true)
|
||||||
@@ -48,10 +39,10 @@ interface ProviderServiceTestInterface extends ProviderBaseInterface {
|
|||||||
*
|
*
|
||||||
* @return array Test results in the format:
|
* @return array Test results in the format:
|
||||||
* [
|
* [
|
||||||
* 'success' => bool,
|
* 'disposition' => 'Success' | 'Failure' | 'Warning',
|
||||||
* 'message' => 'Connection successful' | 'Error message'
|
* 'message' => 'Connection successful' | 'Error message',
|
||||||
* ]
|
* ]
|
||||||
*/
|
*/
|
||||||
public function serviceTest(ServiceBaseInterface $service, array $options = []): array;
|
public function serviceTest(ServiceBaseInterface|ServiceMutableInterface $service, array $options = []): array;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,16 +9,21 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace KTXF\Chrono\Service;
|
namespace KTXF\Chrono\Service;
|
||||||
|
|
||||||
|
use Generator;
|
||||||
use KTXF\Chrono\Collection\CollectionBaseInterface;
|
use KTXF\Chrono\Collection\CollectionBaseInterface;
|
||||||
|
use KTXF\Chrono\Entity\EntityBaseInterface;
|
||||||
use KTXF\Resource\Delta\Delta;
|
use KTXF\Resource\Delta\Delta;
|
||||||
use KTXF\Resource\Filter\IFilter;
|
use KTXF\Resource\Filter\IFilter;
|
||||||
|
use KTXF\Resource\Identifier\EntityIdentifierInterface;
|
||||||
use KTXF\Resource\Provider\ResourceServiceBaseInterface;
|
use KTXF\Resource\Provider\ResourceServiceBaseInterface;
|
||||||
use KTXF\Resource\Range\IRange;
|
use KTXF\Resource\Range\IRange;
|
||||||
use KTXF\Resource\Range\RangeType;
|
use KTXF\Resource\Range\RangeType;
|
||||||
use KTXF\Resource\Sort\ISort;
|
use KTXF\Resource\Sort\ISort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chrono Service Base Interface
|
* Service Base Interface
|
||||||
|
*
|
||||||
|
* Minimum interface for a service, providing read-only access to collections and entities.
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
@@ -70,7 +75,7 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
* @param IFilter|null $filter Optional filter criteria
|
* @param IFilter|null $filter Optional filter criteria
|
||||||
* @param ISort|null $sort Optional sort order
|
* @param ISort|null $sort Optional sort order
|
||||||
*
|
*
|
||||||
* @return array<string|int,CollectionBaseInterface> Collections indexed by ID
|
* @return array<string|int,CollectionBaseInterface> Collections indexed by identifier
|
||||||
*/
|
*/
|
||||||
public function collectionList(string|int $location, ?IFilter $filter = null, ?ISort $sort = null): array;
|
public function collectionList(string|int $location, ?IFilter $filter = null, ?ISort $sort = null): array;
|
||||||
|
|
||||||
@@ -97,9 +102,9 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int ...$identifiers Collection IDs to check
|
* @param string|int ...$identifiers Collection identifiers to check
|
||||||
*
|
*
|
||||||
* @return array<string|int,bool> Map of ID => exists
|
* @return array<string|int,bool> Map of identifier => exists
|
||||||
*/
|
*/
|
||||||
public function collectionExtant(string|int $location, string|int ...$identifiers): array;
|
public function collectionExtant(string|int $location, string|int ...$identifiers): array;
|
||||||
|
|
||||||
@@ -108,29 +113,44 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $identifier Collection ID
|
* @param string|int $identifier Collection identifier
|
||||||
*
|
*
|
||||||
* @return CollectionBaseInterface|null Collection or null if not found
|
* @return CollectionBaseInterface|null Collection or null if not found
|
||||||
*/
|
*/
|
||||||
public function collectionFetch(string|int $identifier): ?CollectionBaseInterface;
|
public function collectionFetch(string|int $identifier): ?CollectionBaseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists messages in a collection
|
* Lists entities in a collection
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection Collection ID
|
* @param string|int $collection Collection identifier
|
||||||
* @param IFilter|null $filter Optional filter criteria
|
* @param IFilter|null $filter Optional filter criteria
|
||||||
* @param ISort|null $sort Optional sort order
|
* @param ISort|null $sort Optional sort order
|
||||||
* @param IRange|null $range Optional pagination
|
* @param IRange|null $range Optional pagination
|
||||||
* @param array|null $properties Optional message properties to fetch
|
* @param array|null $properties Optional entity properties to fetch
|
||||||
*
|
*
|
||||||
* @return array<string|int,EntityBaseInterface> Messages indexed by ID
|
* @return array<string,EntityBaseInterface> Entities indexed by Urn
|
||||||
*/
|
*/
|
||||||
public function entityList(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array;
|
public function entityListBulk(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a filter builder for messages
|
* Lists entities in a collection
|
||||||
|
*
|
||||||
|
* @since 2025.05.01
|
||||||
|
*
|
||||||
|
* @param string|int $collection Collection identifier
|
||||||
|
* @param IFilter|null $filter Optional filter criteria
|
||||||
|
* @param ISort|null $sort Optional sort order
|
||||||
|
* @param IRange|null $range Optional pagination
|
||||||
|
* @param array|null $properties Optional entity properties to fetch
|
||||||
|
*
|
||||||
|
* @return Generator Yields entities one by one as EntityBaseInterface
|
||||||
|
*/
|
||||||
|
public function entityListStream(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): Generator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a filter builder for entities
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
@@ -139,7 +159,7 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
public function entityListFilter(): IFilter;
|
public function entityListFilter(): IFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a sort builder for messages
|
* Creates a sort builder for entities
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
@@ -148,7 +168,7 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
public function entityListSort(): ISort;
|
public function entityListSort(): ISort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a range builder for messages
|
* Creates a range builder for entities
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
@@ -159,40 +179,49 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
public function entityListRange(RangeType $type): IRange;
|
public function entityListRange(RangeType $type): IRange;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets incremental changes since last sync
|
* Gets incremental changes since last signature
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection Collection ID
|
* @param string|int $collection Collection identifier
|
||||||
* @param string $signature Sync token from previous sync
|
* @param string $signature Token from previous delta
|
||||||
* @param string $detail Detail level: 'ids', 'minimal', 'full'
|
|
||||||
*
|
*
|
||||||
* @return array ['signature' => string, 'added' => array, 'modified' => array, 'removed' => array]
|
* @return array ['signature' => string, 'added' => array, 'modified' => array, 'removed' => array]
|
||||||
*/
|
*/
|
||||||
public function entityDelta(string|int $collection, string $signature, string $detail = 'ids'): Delta;
|
public function entityDelta(string|int $collection, string $signature): Delta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if messages exist
|
* Checks if entities exist
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection Collection ID
|
* @param string|int $collection Collection identifier
|
||||||
* @param string|int ...$identifiers Message IDs to check
|
* @param string|int ...$identifiers Entity identifiers to check
|
||||||
*
|
*
|
||||||
* @return array<string|int,bool> Map of ID => exists
|
* @return array<string|int,bool> Map of identifier => exists
|
||||||
*/
|
*/
|
||||||
public function entityExtant(string|int $collection, string|int ...$identifiers): array;
|
public function entityExtant(string|int $collection, string|int ...$identifiers): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches one or more entities
|
* Fetches one or more entities as an array
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection Collection ID
|
* @param EntityIdentifierInterface ...$identifiers Entity identifiers to fetch
|
||||||
* @param string|int ...$identifiers Message IDs to fetch
|
|
||||||
*
|
*
|
||||||
* @return array<string|int,EntityBaseInterface> Messages indexed by ID
|
* @return array<string,EntityBaseInterface> Entities indexed by Urn
|
||||||
*/
|
*/
|
||||||
public function entityFetch(string|int $collection, string|int ...$identifiers): array;
|
public function entityFetchBulk(EntityIdentifierInterface ...$identifiers): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches one or more entities as a stream
|
||||||
|
*
|
||||||
|
* @since 2025.05.01
|
||||||
|
*
|
||||||
|
* @param EntityIdentifierInterface ...$identifiers Entity identifiers to fetch
|
||||||
|
*
|
||||||
|
* @return Generator<string,EntityBaseInterface> Yields entities one by one
|
||||||
|
*/
|
||||||
|
public function entityFetchStream(EntityIdentifierInterface ...$identifiers): Generator;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,13 +11,17 @@ namespace KTXF\Chrono\Service;
|
|||||||
|
|
||||||
use KTXF\Chrono\Collection\CollectionBaseInterface;
|
use KTXF\Chrono\Collection\CollectionBaseInterface;
|
||||||
use KTXF\Chrono\Collection\CollectionMutableInterface;
|
use KTXF\Chrono\Collection\CollectionMutableInterface;
|
||||||
|
use KTXF\Chrono\Collection\CollectionPropertiesBaseInterface;
|
||||||
|
use KTXF\Resource\Identifier\CollectionIdentifierInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chrono Service Collection Mutable Interface
|
* Service Collection Mutable Interface
|
||||||
|
*
|
||||||
|
* Optional interface for services that support collection CRUD operations.
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
interface ServiceCollectionMutableInterface extends ServiceBaseInterface {
|
interface ServiceCollectionMutableInterface {
|
||||||
|
|
||||||
public const CAPABILITY_COLLECTION_CREATE = 'CollectionCreate';
|
public const CAPABILITY_COLLECTION_CREATE = 'CollectionCreate';
|
||||||
public const CAPABILITY_COLLECTION_UPDATE = 'CollectionUpdate';
|
public const CAPABILITY_COLLECTION_UPDATE = 'CollectionUpdate';
|
||||||
@@ -37,37 +41,36 @@ interface ServiceCollectionMutableInterface extends ServiceBaseInterface {
|
|||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int|null $location Parent collection ID (null for root)
|
* @param CollectionIdentifierInterface|null $target Target collection identifier (parent)
|
||||||
* @param CollectionMutableInterface $collection Collection to create
|
* @param CollectionPropertiesBaseInterface $properties Collection properties
|
||||||
* @param array $options Protocol-specific options
|
* @param array $options Protocol-specific options
|
||||||
*
|
*
|
||||||
* @return CollectionBaseInterface Created collection with assigned ID
|
* @return CollectionBaseInterface Created collection with assigned ID
|
||||||
*/
|
*/
|
||||||
public function collectionCreate(string|int|null $location, CollectionMutableInterface $collection, array $options = []): CollectionBaseInterface;
|
public function collectionCreate(CollectionIdentifierInterface|null $target, CollectionPropertiesBaseInterface $properties, array $options = []): CollectionBaseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates an existing collection
|
* Updates an existing collection
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $identifier Collection ID
|
* @param CollectionIdentifierInterface $target Target collection identifier
|
||||||
* @param CollectionMutableInterface $collection Updated collection data
|
* @param CollectionPropertiesBaseInterface $properties Updated collection data
|
||||||
*
|
*
|
||||||
* @return CollectionBaseInterface Updated collection
|
* @return CollectionBaseInterface Updated collection
|
||||||
*/
|
*/
|
||||||
public function collectionUpdate(string|int $identifier, CollectionMutableInterface $collection): CollectionBaseInterface;
|
public function collectionUpdate(CollectionIdentifierInterface $target, CollectionPropertiesBaseInterface $properties): CollectionBaseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a collection
|
* Deletes a collection
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $identifier Collection ID
|
* @param CollectionIdentifierInterface $target Target collection identifier
|
||||||
* @param bool $force Force deletion even if not empty
|
* @param bool $force Force deletion even if not empty
|
||||||
* @param bool $recursive Recursively delete contents
|
|
||||||
*
|
*
|
||||||
* @return bool True if deleted
|
* @return CollectionBaseInterface|true Collection object on soft delete, true on hard delete
|
||||||
*/
|
*/
|
||||||
public function collectionDelete(string|int $identifier, bool $force = false, bool $recursive = false): bool;
|
public function collectionDelete(CollectionIdentifierInterface $target, bool $force = false): CollectionBaseInterface | true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,15 +12,12 @@ namespace KTXF\Chrono\Service;
|
|||||||
use KTXF\Resource\Provider\ResourceServiceConfigureInterface;
|
use KTXF\Resource\Provider\ResourceServiceConfigureInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chrono Service Configurable Interface
|
* Service Configurable Interface
|
||||||
*
|
*
|
||||||
* Extends base service interface with setter methods for mutable properties.
|
* Extends base service interface with setter methods for mutable properties
|
||||||
* Used for service configuration and updates.
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
interface ServiceConfigurableInterface extends ServiceMutableInterface, ResourceServiceConfigureInterface {
|
interface ServiceConfigurableInterface extends ServiceMutableInterface, ResourceServiceConfigureInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = ServiceBaseInterface::JSON_TYPE;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,19 +11,21 @@ namespace KTXF\Chrono\Service;
|
|||||||
|
|
||||||
use KTXF\Chrono\Entity\EntityBaseInterface;
|
use KTXF\Chrono\Entity\EntityBaseInterface;
|
||||||
use KTXF\Chrono\Entity\EntityMutableInterface;
|
use KTXF\Chrono\Entity\EntityMutableInterface;
|
||||||
|
use KTXF\Chrono\Entity\EntityPropertiesMutableInterface;
|
||||||
|
use KTXF\Resource\Identifier\CollectionIdentifierInterface;
|
||||||
|
use KTXF\Resource\Identifier\EntityIdentifierInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chrono Service Entity Mutable Interface
|
* Service Entity Mutable Interface
|
||||||
*
|
*
|
||||||
* Optional interface for services that support entity CRUD operations.
|
* Optional interface for services that support entity CRUD operations
|
||||||
* Provides entity creation, modification, deletion, copying, moving, and flag management.
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
interface ServiceEntityMutableInterface extends ServiceBaseInterface {
|
interface ServiceEntityMutableInterface {
|
||||||
|
|
||||||
public const CAPABILITY_ENTITY_CREATE = 'EntityCreate';
|
public const CAPABILITY_ENTITY_CREATE = 'EntityCreate';
|
||||||
public const CAPABILITY_ENTITY_UPDATE = 'EntityUpdate';
|
public const CAPABILITY_ENTITY_MODIFY = 'EntityModify';
|
||||||
public const CAPABILITY_ENTITY_DELETE = 'EntityDelete';
|
public const CAPABILITY_ENTITY_DELETE = 'EntityDelete';
|
||||||
public const CAPABILITY_ENTITY_COPY = 'EntityCopy';
|
public const CAPABILITY_ENTITY_COPY = 'EntityCopy';
|
||||||
public const CAPABILITY_ENTITY_MOVE = 'EntityMove';
|
public const CAPABILITY_ENTITY_MOVE = 'EntityMove';
|
||||||
@@ -42,36 +44,71 @@ interface ServiceEntityMutableInterface extends ServiceBaseInterface {
|
|||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection collection identifier
|
* @param CollectionIdentifierInterface $target Target collection identifier
|
||||||
* @param EntityMutableInterface $entity Entity data
|
* @param EntityPropertiesMutableInterface $properties Entity properties
|
||||||
* @param array $options additional options
|
* @param array $options Additional options
|
||||||
*
|
*
|
||||||
* @return EntityBaseInterface Created entity
|
* @return EntityBaseInterface Created entity
|
||||||
*/
|
*/
|
||||||
public function entityCreate(string|int $collection, EntityMutableInterface $entity, array $options = []): EntityBaseInterface;
|
public function entityCreate(CollectionIdentifierInterface $target, EntityPropertiesMutableInterface $properties, array $options = []): EntityBaseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifies an existing entity
|
* Modifies an existing entity
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection Collection identifier
|
* @param EntityIdentifierInterface $target Target entity identifier
|
||||||
* @param string|int $identifier Entity identifier
|
* @param EntityPropertiesMutableInterface $properties Entity properties to update
|
||||||
* @param EntityMutableInterface $entity Entity data
|
|
||||||
*
|
*
|
||||||
* @return EntityBaseInterface Modified entity
|
* @return EntityBaseInterface Modified entity
|
||||||
*/
|
*/
|
||||||
public function entityUpdate(string|int $collection, string|int $identifier, EntityMutableInterface $entity): EntityBaseInterface;
|
public function entityModify(EntityIdentifierInterface $target, EntityPropertiesMutableInterface $properties): EntityBaseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes an existing entity in the specified collection
|
* Deletes entities
|
||||||
|
*
|
||||||
|
* @since 2026.04.01
|
||||||
|
*
|
||||||
|
* @param EntityIdentifierInterface ...$targets Source entities to delete
|
||||||
|
*
|
||||||
|
* @return array<string, array{
|
||||||
|
* disposition: 'moved'|'deleted'|'error',
|
||||||
|
* destination: ?CollectionIdentifierInterface,
|
||||||
|
* mutation: EntityIdentifierInterface
|
||||||
|
* }> Results keyed by source entity identifier
|
||||||
|
*/
|
||||||
|
public function entityDelete(EntityIdentifierInterface ...$targets): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves entities to another collection
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection Collection identifier
|
* @param CollectionIdentifierInterface $target Target collection identifier
|
||||||
* @param string|int $identifier Entity identifier to delete
|
* @param EntityIdentifierInterface ...$sources Source entities to move
|
||||||
*
|
*
|
||||||
* @return EntityBaseInterface Deleted entity
|
* @return array<string, array{
|
||||||
|
* disposition: 'moved'|'error',
|
||||||
|
* destination: ?CollectionIdentifierInterface,
|
||||||
|
* mutation: EntityIdentifierInterface
|
||||||
|
* }> Results keyed by source entity identifier
|
||||||
*/
|
*/
|
||||||
public function entityDelete(string|int $collection, string|int $identifier): EntityBaseInterface;
|
public function entityMove(CollectionIdentifierInterface $target, EntityIdentifierInterface ...$sources): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies entities to another collection
|
||||||
|
*
|
||||||
|
* @since 2025.05.01
|
||||||
|
*
|
||||||
|
* @param CollectionIdentifierInterface $target Target collection identifier
|
||||||
|
* @param EntityIdentifierInterface ...$sources Source entities to copy
|
||||||
|
*
|
||||||
|
* @return array<string, array{
|
||||||
|
* disposition: 'copied'|'error',
|
||||||
|
* destination: ?CollectionIdentifierInterface,
|
||||||
|
* mutation: EntityIdentifierInterface
|
||||||
|
* }> Results keyed by source entity identifier
|
||||||
|
*/
|
||||||
|
public function entityCopy(CollectionIdentifierInterface $target, EntityIdentifierInterface ...$sources): array;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,10 @@ namespace KTXF\Chrono\Service;
|
|||||||
/**
|
/**
|
||||||
* Chrono Service Mutable Interface
|
* Chrono Service Mutable Interface
|
||||||
*
|
*
|
||||||
* Extends base service interface with setter methods for mutable properties.
|
* Extends base service interface with setter methods for mutable properties
|
||||||
* Used for service configuration and updates.
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
interface ServiceMutableInterface extends ServiceBaseInterface {
|
interface ServiceMutableInterface {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,16 +14,16 @@ use DateTimeImmutable;
|
|||||||
interface INodeBase extends \JsonSerializable {
|
interface INodeBase extends \JsonSerializable {
|
||||||
|
|
||||||
public const JSON_TYPE = 'files.node';
|
public const JSON_TYPE = 'files.node';
|
||||||
public const JSON_PROPERTY_TYPE = '@type';
|
public const PROPERTY_TYPE = '@type';
|
||||||
public const JSON_PROPERTY_IN = 'in';
|
public const PROPERTY_IN = 'in';
|
||||||
public const JSON_PROPERTY_ID = 'id';
|
public const PROPERTY_ID = 'id';
|
||||||
public const JSON_PROPERTY_CREATED_ON = 'createdOn';
|
public const PROPERTY_CREATED_ON = 'createdOn';
|
||||||
public const JSON_PROPERTY_CREATED_BY = 'createdBy';
|
public const PROPERTY_CREATED_BY = 'createdBy';
|
||||||
public const JSON_PROPERTY_MODIFIED_ON = 'modifiedOn';
|
public const PROPERTY_MODIFIED_ON = 'modifiedOn';
|
||||||
public const JSON_PROPERTY_MODIFIED_BY = 'modifiedBy';
|
public const PROPERTY_MODIFIED_BY = 'modifiedBy';
|
||||||
public const JSON_PROPERTY_OWNER = 'owner';
|
public const PROPERTY_OWNER = 'owner';
|
||||||
public const JSON_PROPERTY_SIGNATURE = 'signature';
|
public const PROPERTY_SIGNATURE = 'signature';
|
||||||
public const JSON_PROPERTY_LABEL = 'label';
|
public const PROPERTY_LABEL = 'label';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unique identifier of the parent node (folder) this node belongs to
|
* Unique identifier of the parent node (folder) this node belongs to
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ namespace KTXF\Files\Node;
|
|||||||
interface INodeEntityBase extends INodeBase {
|
interface INodeEntityBase extends INodeBase {
|
||||||
|
|
||||||
public const JSON_TYPE = 'files.entity';
|
public const JSON_TYPE = 'files.entity';
|
||||||
public const JSON_PROPERTY_SIZE = 'size';
|
public const PROPERTY_SIZE = 'size';
|
||||||
public const JSON_PROPERTY_MIME = 'mime';
|
public const PROPERTY_MIME = 'mime';
|
||||||
public const JSON_PROPERTY_FORMAT = 'format';
|
public const PROPERTY_FORMAT = 'format';
|
||||||
public const JSON_PROPERTY_ENCODING = 'encoding';
|
public const PROPERTY_ENCODING = 'encoding';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File size in bytes
|
* File size in bytes
|
||||||
|
|||||||
@@ -14,15 +14,15 @@ use KTXF\Resource\Identifier\EntityIdentifier;
|
|||||||
use KTXF\Resource\Provider\Node\NodeBaseAbstract;
|
use KTXF\Resource\Provider\Node\NodeBaseAbstract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract Mail Entity Base Class
|
* Abstract Entity Base Class
|
||||||
*
|
*
|
||||||
* Provides common implementation for mail entities
|
* Provides common implementation for entities
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
abstract class EntityBaseAbstract extends NodeBaseAbstract implements EntityBaseInterface {
|
abstract class EntityBaseAbstract extends NodeBaseAbstract implements EntityBaseInterface {
|
||||||
|
|
||||||
protected string $type = 'mail.entity';
|
protected string $type = 'mail:entity';
|
||||||
protected MessagePropertiesBaseInterface $properties;
|
protected MessagePropertiesBaseInterface $properties;
|
||||||
|
|
||||||
protected function nodeIdentifier(): EntityIdentifier {
|
protected function nodeIdentifier(): EntityIdentifier {
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ use KTXF\Resource\Provider\Node\NodeMutableAbstract;
|
|||||||
use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface;
|
use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract Mail Entity Mutable Class
|
* Abstract Entity Mutable Class
|
||||||
*
|
*
|
||||||
* Provides common implementation for mutable mail entities
|
* Provides common implementation for mutable entities
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
abstract class EntityMutableAbstract extends NodeMutableAbstract implements EntityMutableInterface {
|
abstract class EntityMutableAbstract extends NodeMutableAbstract implements EntityMutableInterface {
|
||||||
|
|
||||||
protected string $type = 'mail.entity';
|
protected string $type = 'mail:entity';
|
||||||
protected MessagePropertiesMutableInterface $properties;
|
protected MessagePropertiesMutableInterface $properties;
|
||||||
|
|
||||||
protected function nodeIdentifier(): EntityIdentifier {
|
protected function nodeIdentifier(): EntityIdentifier {
|
||||||
|
|||||||
@@ -25,16 +25,6 @@ class Address implements AddressInterface {
|
|||||||
private ?string $name = null,
|
private ?string $name = null,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function jsonSerialize(): array {
|
|
||||||
return array_filter([
|
|
||||||
self::JSON_PROPERTY_ADDRESS => $this->address,
|
|
||||||
self::JSON_PROPERTY_LABEL => $this->name,
|
|
||||||
], fn($v) => $v !== null && $v !== '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an Address from a formatted string
|
* Creates an Address from a formatted string
|
||||||
*
|
*
|
||||||
@@ -66,17 +56,34 @@ class Address implements AddressInterface {
|
|||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param array $data Array with 'address' and optional 'name' keys
|
* @param array<address: string, label: string|null> $data
|
||||||
*
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public static function fromArray(array $data): self {
|
public static function fromArray(array $data): self {
|
||||||
return new self(
|
return new self(
|
||||||
$data[self::JSON_PROPERTY_ADDRESS] ?? $data['address'] ?? '',
|
$data[self::PROPERTY_ADDRESS] ?? $data['address'] ?? '',
|
||||||
$data[self::JSON_PROPERTY_LABEL] ?? $data['name'] ?? null,
|
$data[self::PROPERTY_LABEL] ?? $data['label'] ?? null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function jsonSerialize(): array {
|
||||||
|
return array_filter([
|
||||||
|
self::PROPERTY_ADDRESS => $this->address,
|
||||||
|
self::PROPERTY_LABEL => $this->name,
|
||||||
|
], fn($v) => $v !== null && $v !== '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function toArray(): array {
|
||||||
|
return $this->jsonSerialize();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -20,8 +20,15 @@ use KTXF\Json\JsonSerializable;
|
|||||||
*/
|
*/
|
||||||
interface AddressInterface extends JsonSerializable {
|
interface AddressInterface extends JsonSerializable {
|
||||||
|
|
||||||
public const JSON_PROPERTY_ADDRESS = 'address';
|
public const PROPERTY_ADDRESS = 'address';
|
||||||
public const JSON_PROPERTY_LABEL = 'label';
|
public const PROPERTY_LABEL = 'label';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Converts the Address to an array representation
|
||||||
|
*
|
||||||
|
* @return array<address: string, label: string|null>
|
||||||
|
*/
|
||||||
|
public function toArray(): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the email address
|
* Gets the email address
|
||||||
|
|||||||
@@ -1,194 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace KTXF\Mail\Object;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attachment Implementation
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*/
|
|
||||||
class Attachment implements AttachmentInterface {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $name File name
|
|
||||||
* @param string $mimeType MIME type
|
|
||||||
* @param string $content Binary content
|
|
||||||
* @param string|null $id Attachment ID
|
|
||||||
* @param int|null $size Size in bytes
|
|
||||||
* @param string|null $contentId Content-ID for inline attachments
|
|
||||||
* @param bool $inline Whether inline attachment
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
private string $name,
|
|
||||||
private string $mimeType,
|
|
||||||
private string $content,
|
|
||||||
private ?string $id = null,
|
|
||||||
private ?int $size = null,
|
|
||||||
private ?string $contentId = null,
|
|
||||||
private bool $inline = false,
|
|
||||||
) {
|
|
||||||
if ($this->size === null) {
|
|
||||||
$this->size = strlen($this->content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function jsonSerialize(): array {
|
|
||||||
return array_filter([
|
|
||||||
self::JSON_PROPERTY_ID => $this->id,
|
|
||||||
self::JSON_PROPERTY_NAME => $this->name,
|
|
||||||
self::JSON_PROPERTY_MIME_TYPE => $this->mimeType,
|
|
||||||
self::JSON_PROPERTY_SIZE => $this->size,
|
|
||||||
self::JSON_PROPERTY_CONTENT_ID => $this->contentId,
|
|
||||||
self::JSON_PROPERTY_INLINE => $this->inline ?: null,
|
|
||||||
'contentBase64' => $this->getContentBase64(),
|
|
||||||
], fn($v) => $v !== null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an attachment from a file path
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @param string $path File path
|
|
||||||
* @param string|null $name Override file name
|
|
||||||
* @param string|null $mimeType Override MIME type
|
|
||||||
*
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public static function fromFile(string $path, ?string $name = null, ?string $mimeType = null): self {
|
|
||||||
$content = file_get_contents($path);
|
|
||||||
$name = $name ?? basename($path);
|
|
||||||
$mimeType = $mimeType ?? mime_content_type($path) ?: 'application/octet-stream';
|
|
||||||
|
|
||||||
return new self($name, $mimeType, $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an attachment from base64 encoded content
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @param string $name File name
|
|
||||||
* @param string $mimeType MIME type
|
|
||||||
* @param string $base64Content Base64 encoded content
|
|
||||||
*
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public static function fromBase64(string $name, string $mimeType, string $base64Content): self {
|
|
||||||
return new self($name, $mimeType, base64_decode($base64Content));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an inline attachment for embedding in HTML
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @param string $name File name
|
|
||||||
* @param string $mimeType MIME type
|
|
||||||
* @param string $content Binary content
|
|
||||||
* @param string $contentId Content-ID (without cid: prefix)
|
|
||||||
*
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public static function inline(string $name, string $mimeType, string $content, string $contentId): self {
|
|
||||||
return new self($name, $mimeType, $content, null, null, $contentId, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates from array data
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
*
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public static function fromArray(array $data): self {
|
|
||||||
$content = $data['content'] ?? '';
|
|
||||||
if (isset($data['contentBase64'])) {
|
|
||||||
$content = base64_decode($data['contentBase64']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new self(
|
|
||||||
$data[self::JSON_PROPERTY_NAME] ?? $data['name'] ?? '',
|
|
||||||
$data[self::JSON_PROPERTY_MIME_TYPE] ?? $data['mimeType'] ?? 'application/octet-stream',
|
|
||||||
$content,
|
|
||||||
$data[self::JSON_PROPERTY_ID] ?? $data['id'] ?? null,
|
|
||||||
$data[self::JSON_PROPERTY_SIZE] ?? $data['size'] ?? null,
|
|
||||||
$data[self::JSON_PROPERTY_CONTENT_ID] ?? $data['contentId'] ?? null,
|
|
||||||
$data[self::JSON_PROPERTY_INLINE] ?? $data['inline'] ?? false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function getId(): ?string {
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function getName(): string {
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function getMimeType(): string {
|
|
||||||
return $this->mimeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function getSize(): ?int {
|
|
||||||
return $this->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function getContentId(): ?string {
|
|
||||||
return $this->contentId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function isInline(): bool {
|
|
||||||
return $this->inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function getContent(): string {
|
|
||||||
return $this->content;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the content as base64 encoded string
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getContentBase64(): string {
|
|
||||||
return base64_encode($this->content);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace KTXF\Mail\Object;
|
|
||||||
|
|
||||||
use KTXF\Json\JsonSerializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attachment Interface
|
|
||||||
*
|
|
||||||
* Represents a file attachment on a mail message.
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*/
|
|
||||||
interface AttachmentInterface extends JsonSerializable {
|
|
||||||
|
|
||||||
public const JSON_PROPERTY_ID = 'id';
|
|
||||||
public const JSON_PROPERTY_NAME = 'name';
|
|
||||||
public const JSON_PROPERTY_MIME_TYPE = 'mimeType';
|
|
||||||
public const JSON_PROPERTY_SIZE = 'size';
|
|
||||||
public const JSON_PROPERTY_CONTENT_ID = 'contentId';
|
|
||||||
public const JSON_PROPERTY_INLINE = 'inline';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the attachment identifier
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @return string|null Attachment ID or null for new attachments
|
|
||||||
*/
|
|
||||||
public function getId(): ?string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the file name
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @return string File name (e.g., "document.pdf")
|
|
||||||
*/
|
|
||||||
public function getName(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MIME type
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @return string MIME type (e.g., "application/pdf")
|
|
||||||
*/
|
|
||||||
public function getMimeType(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the file size in bytes
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @return int|null Size in bytes or null if unknown
|
|
||||||
*/
|
|
||||||
public function getSize(): ?int;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Content-ID for inline attachments
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @return string|null Content-ID for referencing in HTML body (e.g., "cid:image1")
|
|
||||||
*/
|
|
||||||
public function getContentId(): ?string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this is an inline attachment (embedded in body)
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @return bool True if inline, false if regular attachment
|
|
||||||
*/
|
|
||||||
public function isInline(): bool;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the attachment content
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @return string Binary content of the attachment
|
|
||||||
*/
|
|
||||||
public function getContent(): string;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace KTXF\Mail\Object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared Message Part implementation matching the frontend JSON shape.
|
||||||
|
*/
|
||||||
|
class MessagePart extends MessagePartMutableAbstract {
|
||||||
|
|
||||||
|
public static function fromArray(array $data): self {
|
||||||
|
$part = new self();
|
||||||
|
$part->data = $data;
|
||||||
|
|
||||||
|
if (isset($part->data[MessagePartInterface::PROPERTY_SUB_PARTS]) && is_array($part->data[MessagePartInterface::PROPERTY_SUB_PARTS])) {
|
||||||
|
foreach ($part->data[MessagePartInterface::PROPERTY_SUB_PARTS] as $entry) {
|
||||||
|
if (is_object($entry)) {
|
||||||
|
$entry = get_object_vars($entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($entry)) {
|
||||||
|
$part->parts[] = self::fromArray($entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($part->data[MessagePartInterface::PROPERTY_SUB_PARTS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $part;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,9 +32,9 @@ abstract class MessagePartBaseAbstract implements MessagePartInterface {
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param array &$data Reference to data array
|
* @param array|null &$data Reference to data array
|
||||||
*/
|
*/
|
||||||
public function __construct(array &$data = null) {
|
public function __construct(array|null &$data = null) {
|
||||||
if ($data === null) {
|
if ($data === null) {
|
||||||
$data = [];
|
$data = [];
|
||||||
}
|
}
|
||||||
@@ -52,49 +52,70 @@ abstract class MessagePartBaseAbstract implements MessagePartInterface {
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getId(): ?string {
|
public function getId(): ?string {
|
||||||
return $this->data['partId'] ?? null;
|
return $this->data[MessagePartInterface::PROPERTY_PART_ID] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getSize(): ?int {
|
||||||
|
return $this->data[MessagePartInterface::PROPERTY_SIZE] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getType(): ?string {
|
public function getType(): ?string {
|
||||||
return $this->data['type'] ?? null;
|
return $this->data[MessagePartInterface::PROPERTY_TYPE] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getDisposition(): ?string {
|
public function getDisposition(): ?string {
|
||||||
return $this->data['disposition'] ?? null;
|
return $this->data[MessagePartInterface::PROPERTY_DISPOSITION] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getName(): ?string {
|
public function getName(): ?string {
|
||||||
return $this->data['name'] ?? null;
|
return $this->data[MessagePartInterface::PROPERTY_NAME] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getCharset(): ?string {
|
public function getCharset(): ?string {
|
||||||
return $this->data['charset'] ?? null;
|
return $this->data[MessagePartInterface::PROPERTY_CHARSET] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getContentId(): ?string {
|
||||||
|
return $this->data[MessagePartInterface::PROPERTY_CONTENT_ID] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getLanguage(): ?string {
|
public function getLanguage(): ?string {
|
||||||
return $this->data['language'] ?? null;
|
return $this->data[MessagePartInterface::PROPERTY_LANGUAGE] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getLocation(): ?string {
|
public function getLocation(): ?string {
|
||||||
return $this->data['location'] ?? null;
|
return $this->data[MessagePartInterface::PROPERTY_LOCATION] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getContent(): ?string {
|
||||||
|
return $this->data[MessagePartInterface::PROPERTY_CONTENT] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,9 +132,9 @@ abstract class MessagePartBaseAbstract implements MessagePartInterface {
|
|||||||
$result = $this->data;
|
$result = $this->data;
|
||||||
|
|
||||||
if (!empty($this->parts)) {
|
if (!empty($this->parts)) {
|
||||||
$result['subParts'] = [];
|
$result[MessagePartInterface::PROPERTY_SUB_PARTS] = [];
|
||||||
foreach ($this->parts as $part) {
|
foreach ($this->parts as $part) {
|
||||||
$result['subParts'][] = $part->jsonSerialize();
|
$result[MessagePartInterface::PROPERTY_SUB_PARTS][] = $part->jsonSerialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,19 @@ use KTXF\Json\JsonSerializable;
|
|||||||
*/
|
*/
|
||||||
interface MessagePartInterface extends JsonSerializable {
|
interface MessagePartInterface extends JsonSerializable {
|
||||||
|
|
||||||
|
public const PROPERTY_PART_ID = 'partId';
|
||||||
|
public const PROPERTY_BLOB_ID = 'blobId';
|
||||||
|
public const PROPERTY_SIZE = 'size';
|
||||||
|
public const PROPERTY_NAME = 'name';
|
||||||
|
public const PROPERTY_TYPE = 'type';
|
||||||
|
public const PROPERTY_CHARSET = 'charset';
|
||||||
|
public const PROPERTY_DISPOSITION = 'disposition';
|
||||||
|
public const PROPERTY_CONTENT_ID = 'cid';
|
||||||
|
public const PROPERTY_LANGUAGE = 'language';
|
||||||
|
public const PROPERTY_LOCATION = 'location';
|
||||||
|
public const PROPERTY_CONTENT = 'content';
|
||||||
|
public const PROPERTY_SUB_PARTS = 'subParts';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the blob identifier
|
* Gets the blob identifier
|
||||||
*
|
*
|
||||||
@@ -38,6 +51,15 @@ interface MessagePartInterface extends JsonSerializable {
|
|||||||
*/
|
*/
|
||||||
public function getId(): ?string;
|
public function getId(): ?string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the part size in bytes
|
||||||
|
*
|
||||||
|
* @since 2026.06.15
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
public function getSize(): ?int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the MIME type
|
* Gets the MIME type
|
||||||
*
|
*
|
||||||
@@ -56,6 +78,15 @@ interface MessagePartInterface extends JsonSerializable {
|
|||||||
*/
|
*/
|
||||||
public function getDisposition(): ?string;
|
public function getDisposition(): ?string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Content-ID for inline parts
|
||||||
|
*
|
||||||
|
* @since 2026.06.15
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getContentId(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the part name
|
* Gets the part name
|
||||||
*
|
*
|
||||||
@@ -92,6 +123,15 @@ interface MessagePartInterface extends JsonSerializable {
|
|||||||
*/
|
*/
|
||||||
public function getLocation(): ?string;
|
public function getLocation(): ?string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the decoded part content
|
||||||
|
*
|
||||||
|
* @since 2026.06.15
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getContent(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the sub-parts
|
* Gets the sub-parts
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -46,6 +46,16 @@ abstract class MessagePartMutableAbstract extends MessagePartBaseAbstract {
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the part size
|
||||||
|
*
|
||||||
|
* @since 2026.06.15
|
||||||
|
*/
|
||||||
|
public function setSize(?int $value): static {
|
||||||
|
$this->data['size'] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the MIME type
|
* Sets the MIME type
|
||||||
*
|
*
|
||||||
@@ -102,6 +112,16 @@ abstract class MessagePartMutableAbstract extends MessagePartBaseAbstract {
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the content id
|
||||||
|
*
|
||||||
|
* @since 2026.06.15
|
||||||
|
*/
|
||||||
|
public function setContentId(?string $value): static {
|
||||||
|
$this->data['cid'] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the language
|
* Sets the language
|
||||||
*
|
*
|
||||||
@@ -130,6 +150,16 @@ abstract class MessagePartMutableAbstract extends MessagePartBaseAbstract {
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the content payload
|
||||||
|
*
|
||||||
|
* @since 2026.06.15
|
||||||
|
*/
|
||||||
|
public function setContent(?string $value): static {
|
||||||
|
$this->data['content'] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the sub-parts
|
* Sets the sub-parts
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace KTXF\Mail\Object;
|
namespace KTXF\Mail\Object;
|
||||||
|
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
|
use Exception;
|
||||||
use KTXF\Resource\Provider\Node\NodePropertiesBaseAbstract;
|
use KTXF\Resource\Provider\Node\NodePropertiesBaseAbstract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,7 +22,110 @@ use KTXF\Resource\Provider\Node\NodePropertiesBaseAbstract;
|
|||||||
*/
|
*/
|
||||||
abstract class MessagePropertiesBaseAbstract extends NodePropertiesBaseAbstract implements MessagePropertiesBaseInterface {
|
abstract class MessagePropertiesBaseAbstract extends NodePropertiesBaseAbstract implements MessagePropertiesBaseInterface {
|
||||||
|
|
||||||
protected string $type = 'mail.message';
|
protected string $type = 'mail:message';
|
||||||
|
|
||||||
|
protected function extractBodyContent(?MessagePartInterface $part, string $type): ?string {
|
||||||
|
if ($part === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($part->getType() === $type) {
|
||||||
|
$content = $part->getContent();
|
||||||
|
return is_string($content) && $content !== '' ? $content : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($part->getParts() as $subPart) {
|
||||||
|
$content = $this->extractBodyContent($subPart, $type);
|
||||||
|
if ($content !== null) {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function materializeAddress(mixed $value): ?AddressInterface {
|
||||||
|
if ($value instanceof AddressInterface) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($value) && $value !== '') {
|
||||||
|
return Address::fromString($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($value) || $value === []) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_is_list($value)) {
|
||||||
|
return $this->materializeAddress($value[0] ?? null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Address::fromArray([
|
||||||
|
AddressInterface::PROPERTY_ADDRESS => $value[AddressInterface::PROPERTY_ADDRESS],
|
||||||
|
AddressInterface::PROPERTY_LABEL => $value[AddressInterface::PROPERTY_LABEL] ?? null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int,AddressInterface>
|
||||||
|
*/
|
||||||
|
protected function materializeAddresses(array $values): array {
|
||||||
|
$addresses = [];
|
||||||
|
|
||||||
|
foreach ($values as $value) {
|
||||||
|
$address = $this->materializeAddress($value);
|
||||||
|
if ($address !== null) {
|
||||||
|
$addresses[] = $address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function materializeDate(mixed $value): ?DateTimeImmutable {
|
||||||
|
if ($value instanceof DateTimeImmutable) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_string($value) || $value === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new DateTimeImmutable($value);
|
||||||
|
} catch (Exception) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function materializePart(mixed $value): ?MessagePartInterface {
|
||||||
|
if ($value instanceof MessagePartInterface) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($value) || $value === []) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MessagePart::fromArray($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int,MessagePartInterface>
|
||||||
|
*/
|
||||||
|
protected function materializeParts(array $values): array {
|
||||||
|
$parts = [];
|
||||||
|
|
||||||
|
foreach ($values as $value) {
|
||||||
|
$part = $this->materializePart($value);
|
||||||
|
if ($part !== null) {
|
||||||
|
$parts[] = $part;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parts;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
@@ -76,56 +180,56 @@ abstract class MessagePropertiesBaseAbstract extends NodePropertiesBaseAbstract
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getReceived(): ?DateTimeImmutable {
|
public function getReceived(): ?DateTimeImmutable {
|
||||||
return $this->data[static::PROPERTY_RECEIVED] ?? null;
|
return $this->materializeDate($this->data[static::PROPERTY_RECEIVED] ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getSent(): ?DateTimeImmutable {
|
public function getSent(): ?DateTimeImmutable {
|
||||||
return $this->data[static::PROPERTY_SENT] ?? null;
|
return $this->materializeDate($this->data[static::PROPERTY_SENT] ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getSender(): ?AddressInterface {
|
public function getSender(): ?AddressInterface {
|
||||||
return $this->data[static::PROPERTY_SENDER] ?? null;
|
return $this->materializeAddress($this->data[static::PROPERTY_SENDER] ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getFrom(): ?AddressInterface {
|
public function getFrom(): ?AddressInterface {
|
||||||
return $this->data[static::PROPERTY_FROM] ?? null;
|
return $this->materializeAddress($this->data[static::PROPERTY_FROM] ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getReplyTo(): array {
|
public function getReplyTo(): array {
|
||||||
return $this->data[static::PROPERTY_REPLY_TO] ?? [];
|
return $this->materializeAddresses($this->data[static::PROPERTY_REPLY_TO] ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getTo(): array {
|
public function getTo(): array {
|
||||||
return $this->data[static::PROPERTY_TO] ?? [];
|
return $this->materializeAddresses($this->data[static::PROPERTY_TO] ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getCc(): array {
|
public function getCc(): array {
|
||||||
return $this->data[static::PROPERTY_CC] ?? [];
|
return $this->materializeAddresses($this->data[static::PROPERTY_CC] ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getBcc(): array {
|
public function getBcc(): array {
|
||||||
return $this->data[static::PROPERTY_BCC] ?? [];
|
return $this->materializeAddresses($this->data[static::PROPERTY_BCC] ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,36 +243,38 @@ abstract class MessagePropertiesBaseAbstract extends NodePropertiesBaseAbstract
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getBody(): ?MessagePartInterface {
|
public function getBody(): ?MessagePartInterface {
|
||||||
return $this->data[static::PROPERTY_BODY] ?? null;
|
return $this->materializePart($this->data[static::PROPERTY_BODY] ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function hasBody(): bool {
|
public function hasBody(): bool {
|
||||||
return ($this->data[static::PROPERTY_BODY_TEXT_PLAIN] !== null && $this->data[static::PROPERTY_BODY_TEXT_PLAIN] !== '')
|
$body = $this->getBody();
|
||||||
|| ($this->data[static::PROPERTY_BODY_TEXT_HTML] !== null && $this->data[static::PROPERTY_BODY_TEXT_HTML] !== '');
|
|
||||||
|
return $this->extractBodyContent($body, 'text/plain') !== null
|
||||||
|
|| $this->extractBodyContent($body, 'text/html') !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getBodyTextPlain(): ?string {
|
public function getBodyTextPlain(): ?string {
|
||||||
return $this->data[static::PROPERTY_BODY_TEXT_PLAIN] ?? null;
|
return $this->extractBodyContent($this->getBody(), 'text/plain');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getBodyTextHtml(): ?string {
|
public function getBodyTextHtml(): ?string {
|
||||||
return $this->data[static::PROPERTY_BODY_TEXT_HTML] ?? null;
|
return $this->extractBodyContent($this->getBody(), 'text/html');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getAttachments(): array {
|
public function getAttachments(): array {
|
||||||
return $this->data[static::PROPERTY_ATTACHMENTS] ?? [];
|
return $this->materializeParts($this->data[static::PROPERTY_ATTACHMENTS] ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,7 +282,7 @@ abstract class MessagePropertiesBaseAbstract extends NodePropertiesBaseAbstract
|
|||||||
*/
|
*/
|
||||||
public function getFlags(): array {
|
public function getFlags(): array {
|
||||||
return $this->data[static::PROPERTY_FLAGS] ?? [
|
return $this->data[static::PROPERTY_FLAGS] ?? [
|
||||||
'read' => false,
|
'seen' => false,
|
||||||
'starred' => false,
|
'starred' => false,
|
||||||
'important' => false,
|
'important' => false,
|
||||||
'answered' => false,
|
'answered' => false,
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ interface MessagePropertiesBaseInterface extends NodePropertiesBaseInterface {
|
|||||||
public const PROPERTY_BCC = 'bcc';
|
public const PROPERTY_BCC = 'bcc';
|
||||||
public const PROPERTY_SUBJECT = 'subject';
|
public const PROPERTY_SUBJECT = 'subject';
|
||||||
public const PROPERTY_BODY = 'body';
|
public const PROPERTY_BODY = 'body';
|
||||||
public const PROPERTY_BODY_TEXT_PLAIN = 'bodyTextPlain';
|
|
||||||
public const PROPERTY_BODY_TEXT_HTML = 'bodyTextHtml';
|
|
||||||
public const PROPERTY_ATTACHMENTS = 'attachments';
|
public const PROPERTY_ATTACHMENTS = 'attachments';
|
||||||
public const PROPERTY_FLAGS = 'flags';
|
public const PROPERTY_FLAGS = 'flags';
|
||||||
public const PROPERTY_TAGS = 'tags';
|
public const PROPERTY_TAGS = 'tags';
|
||||||
@@ -217,7 +215,7 @@ interface MessagePropertiesBaseInterface extends NodePropertiesBaseInterface {
|
|||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @return array<int,AttachmentInterface>
|
* @return array<int,MessagePartInterface>
|
||||||
*/
|
*/
|
||||||
public function getAttachments(): array;
|
public function getAttachments(): array;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace KTXF\Mail\Object;
|
namespace KTXF\Mail\Object;
|
||||||
|
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
|
use DateTimeInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract Message Properties Mutable Class
|
* Abstract Message Properties Mutable Class
|
||||||
@@ -22,6 +23,90 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
|
|
||||||
protected string $type = 'mail.message';
|
protected string $type = 'mail.message';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int,AddressInterface> $values
|
||||||
|
*
|
||||||
|
* @return array<int,array<string,string|null>>
|
||||||
|
*/
|
||||||
|
protected function normalizeAddresses(array $values): array {
|
||||||
|
return array_map(
|
||||||
|
static fn(AddressInterface $value): array => $value->toArray(),
|
||||||
|
$values,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function normalizeDate(?DateTimeImmutable $value): ?string {
|
||||||
|
return $value?->format(DATE_ATOM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int,MessagePartInterface> $values
|
||||||
|
*
|
||||||
|
* @return array<int,array<string,mixed>>
|
||||||
|
*/
|
||||||
|
protected function normalizeParts(array $values): array {
|
||||||
|
return array_map(
|
||||||
|
static fn(MessagePartInterface $value): array => $value->jsonSerialize(),
|
||||||
|
$values,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildBodyPartFromContent(?string $textPlain, ?string $textHtml): ?MessagePart {
|
||||||
|
$hasTextPlain = is_string($textPlain) && $textPlain !== '';
|
||||||
|
$hasTextHtml = is_string($textHtml) && $textHtml !== '';
|
||||||
|
|
||||||
|
if (!$hasTextPlain && !$hasTextHtml) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($hasTextPlain && $hasTextHtml) {
|
||||||
|
return MessagePart::fromArray([
|
||||||
|
'partId' => 'body',
|
||||||
|
'type' => 'multipart/alternative',
|
||||||
|
'subParts' => [
|
||||||
|
[
|
||||||
|
'partId' => 'body.text',
|
||||||
|
'type' => 'text/plain',
|
||||||
|
'charset' => 'utf-8',
|
||||||
|
'content' => $textPlain,
|
||||||
|
'disposition' => 'inline',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'partId' => 'body.html',
|
||||||
|
'type' => 'text/html',
|
||||||
|
'charset' => 'utf-8',
|
||||||
|
'content' => $textHtml,
|
||||||
|
'disposition' => 'inline',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MessagePart::fromArray([
|
||||||
|
'partId' => 'body',
|
||||||
|
'type' => $hasTextHtml ? 'text/html' : 'text/plain',
|
||||||
|
'charset' => 'utf-8',
|
||||||
|
'content' => $hasTextHtml ? $textHtml : $textPlain,
|
||||||
|
'disposition' => 'inline',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function updateBodyContent(string $type, ?string $value): static {
|
||||||
|
$currentPlain = $this->getBodyTextPlain();
|
||||||
|
$currentHtml = $this->getBodyTextHtml();
|
||||||
|
|
||||||
|
if ($type === 'text/plain') {
|
||||||
|
$currentPlain = $value;
|
||||||
|
} else {
|
||||||
|
$currentHtml = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->data[static::PROPERTY_BODY] = $this->buildBodyPartFromContent($currentPlain, $currentHtml)?->jsonSerialize();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@@ -91,16 +176,16 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setReceived(?DateTimeImmutable $value): static {
|
public function setReceived(?DateTimeInterface $value): static {
|
||||||
$this->data[static::PROPERTY_RECEIVED] = $value;
|
$this->data[static::PROPERTY_RECEIVED] = $this->normalizeDate($value);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setSent(DateTimeImmutable $value): static {
|
public function setSent(?DateTimeInterface $value): static {
|
||||||
$this->data[static::PROPERTY_SENT] = $value;
|
$this->data[static::PROPERTY_SENT] = $this->normalizeDate($value);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +193,7 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setSender(?AddressInterface $value): static {
|
public function setSender(?AddressInterface $value): static {
|
||||||
$this->data[static::PROPERTY_SENDER] = $value;
|
$this->data[static::PROPERTY_SENDER] = $value?->toArray();
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +201,7 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setFrom(AddressInterface $value): static {
|
public function setFrom(AddressInterface $value): static {
|
||||||
$this->data[static::PROPERTY_FROM] = $value;
|
$this->data[static::PROPERTY_FROM] = $value->toArray();
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +209,7 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setReplyTo(AddressInterface ...$value): static {
|
public function setReplyTo(AddressInterface ...$value): static {
|
||||||
$this->data[static::PROPERTY_REPLY_TO] = $value;
|
$this->data[static::PROPERTY_REPLY_TO] = $this->normalizeAddresses($value);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +217,7 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setTo(AddressInterface ...$value): static {
|
public function setTo(AddressInterface ...$value): static {
|
||||||
$this->data[static::PROPERTY_TO] = $value;
|
$this->data[static::PROPERTY_TO] = $this->normalizeAddresses($value);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +225,7 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setCc(AddressInterface ...$value): static {
|
public function setCc(AddressInterface ...$value): static {
|
||||||
$this->data[static::PROPERTY_CC] = $value;
|
$this->data[static::PROPERTY_CC] = $this->normalizeAddresses($value);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +233,7 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setBcc(AddressInterface ...$value): static {
|
public function setBcc(AddressInterface ...$value): static {
|
||||||
$this->data[static::PROPERTY_BCC] = $value;
|
$this->data[static::PROPERTY_BCC] = $this->normalizeAddresses($value);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +249,7 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setBody(?MessagePartInterface $value): static {
|
public function setBody(?MessagePartInterface $value): static {
|
||||||
$this->data[static::PROPERTY_BODY] = $value;
|
$this->data[static::PROPERTY_BODY] = $value?->jsonSerialize();
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,31 +257,29 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setBodyTextPlain(?string $value): static {
|
public function setBodyTextPlain(?string $value): static {
|
||||||
$this->data[static::PROPERTY_BODY_TEXT_PLAIN] = $value;
|
return $this->updateBodyContent('text/plain', $value);
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setBodyTextHtml(?string $value): static {
|
public function setBodyTextHtml(?string $value): static {
|
||||||
$this->data[static::PROPERTY_BODY_TEXT_HTML] = $value;
|
return $this->updateBodyContent('text/html', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function setAttachments(\KTXF\Mail\Object\MessagePartInterface ...$value): static {
|
||||||
|
$this->data[static::PROPERTY_ATTACHMENTS] = $this->normalizeParts($value);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setAttachments(AttachmentInterface ...$value): static {
|
public function addAttachment(\KTXF\Mail\Object\MessagePartInterface $value): static {
|
||||||
$this->data[static::PROPERTY_ATTACHMENTS] = $value;
|
$this->data[static::PROPERTY_ATTACHMENTS][] = $value->jsonSerialize();
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function addAttachment(AttachmentInterface $value): static {
|
|
||||||
$this->data[static::PROPERTY_ATTACHMENTS][] = $value;
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,7 +295,7 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
public function setFlags(array $value): static {
|
public function setFlags(array $value): static {
|
||||||
if (!isset($this->data[static::PROPERTY_FLAGS])) {
|
if (!isset($this->data[static::PROPERTY_FLAGS])) {
|
||||||
$this->data[static::PROPERTY_FLAGS] = [
|
$this->data[static::PROPERTY_FLAGS] = [
|
||||||
'read' => false,
|
'seen' => false,
|
||||||
'starred' => false,
|
'starred' => false,
|
||||||
'important' => false,
|
'important' => false,
|
||||||
'answered' => false,
|
'answered' => false,
|
||||||
@@ -232,7 +315,7 @@ abstract class MessagePropertiesMutableAbstract extends MessagePropertiesBaseAbs
|
|||||||
public function setFlag(string $name, bool $value): static {
|
public function setFlag(string $name, bool $value): static {
|
||||||
if (!isset($this->data[static::PROPERTY_FLAGS])) {
|
if (!isset($this->data[static::PROPERTY_FLAGS])) {
|
||||||
$this->data[static::PROPERTY_FLAGS] = [
|
$this->data[static::PROPERTY_FLAGS] = [
|
||||||
'read' => false,
|
'seen' => false,
|
||||||
'starred' => false,
|
'starred' => false,
|
||||||
'important' => false,
|
'important' => false,
|
||||||
'answered' => false,
|
'answered' => false,
|
||||||
|
|||||||
@@ -223,22 +223,22 @@ interface MessagePropertiesMutableInterface extends MessagePropertiesBaseInterfa
|
|||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param AttachmentInterface ...$value
|
* @param MessagePartInterface ...$value
|
||||||
*
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function setAttachments(AttachmentInterface ...$value): static;
|
public function setAttachments(MessagePartInterface ...$value): static;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an attachment
|
* Adds an attachment
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param AttachmentInterface $value
|
* @param MessagePartInterface $value
|
||||||
*
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function addAttachment(AttachmentInterface $value): static;
|
public function addAttachment(MessagePartInterface $value): static;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets message flags
|
* Sets message flags
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ use KTXF\Mail\Service\ServiceBaseInterface;
|
|||||||
use KTXF\Resource\Provider\ResourceProviderBaseInterface;
|
use KTXF\Resource\Provider\ResourceProviderBaseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mail Provider Base Interface
|
* Provider Base Interface
|
||||||
*
|
*
|
||||||
* Core interface for mail providers with context-aware service discovery.
|
* Core interface for providers with context-aware service discovery.
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
interface ProviderBaseInterface extends ResourceProviderBaseInterface{
|
interface ProviderBaseInterface extends ResourceProviderBaseInterface{
|
||||||
|
|
||||||
public const JSON_TYPE = 'mail.provider';
|
public const JSON_TYPE = 'mail:provider';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a service that handles a specific email address
|
* Finds a service that handles a specific email address
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ namespace KTXF\Mail\Provider;
|
|||||||
use KTXF\Resource\Provider\ResourceServiceLocationInterface;
|
use KTXF\Resource\Provider\ResourceServiceLocationInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mail Provider Autodiscovery Interface
|
* Provider Autodiscovery Interface
|
||||||
*
|
*
|
||||||
* Optional interface for mail providers that support automatic service discovery
|
* Optional interface for providers that support automatic service discovery
|
||||||
* from email addresses or domains. Providers implementing this interface can
|
* from email addresses or domains. Providers implementing this interface can
|
||||||
* discover mail service configurations using various methods specific to their
|
* discover service configurations using various methods specific to their
|
||||||
* protocol or provider type.
|
* protocol or provider type.
|
||||||
*
|
*
|
||||||
* Examples:
|
* Examples:
|
||||||
@@ -28,6 +28,8 @@ use KTXF\Resource\Provider\ResourceServiceLocationInterface;
|
|||||||
*/
|
*/
|
||||||
interface ProviderServiceDiscoverInterface {
|
interface ProviderServiceDiscoverInterface {
|
||||||
|
|
||||||
|
public const CAPABILITY_SERVICE_DISCOVER = 'ServiceDiscover';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to discover service configuration using provider-specific methods.
|
* Attempts to discover service configuration using provider-specific methods.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,11 +12,9 @@ namespace KTXF\Mail\Provider;
|
|||||||
use KTXF\Resource\Provider\ResourceProviderServiceMutateInterface;
|
use KTXF\Resource\Provider\ResourceProviderServiceMutateInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mail Provider Service Mutate Interface
|
* Provider Service Mutate Interface
|
||||||
*
|
*
|
||||||
* Optional interface for providers that support service CRUD operations.
|
* Optional interface for providers that support service CRUD operations
|
||||||
*
|
|
||||||
* Implementations return ServiceMutableInterface instances (which extend ResourceServiceMutateInterface).
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
@@ -28,6 +26,5 @@ use KTXF\Resource\Provider\ResourceProviderServiceMutateInterface;
|
|||||||
interface ProviderServiceMutateInterface extends ResourceProviderServiceMutateInterface {
|
interface ProviderServiceMutateInterface extends ResourceProviderServiceMutateInterface {
|
||||||
|
|
||||||
// Methods inherited from ResourceProviderServiceMutateInterface
|
// Methods inherited from ResourceProviderServiceMutateInterface
|
||||||
// Implementations should return/accept ServiceMutableInterface instances
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,30 +13,20 @@ use KTXF\Mail\Service\ServiceBaseInterface;
|
|||||||
use KTXF\Mail\Service\ServiceMutableInterface;
|
use KTXF\Mail\Service\ServiceMutableInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mail Provider Service Test Interface
|
* Provider Service Test Interface
|
||||||
*
|
*
|
||||||
* Optional interface for mail providers that support testing service connections.
|
* Optional interface for providers that support testing service connections
|
||||||
* Providers implementing this interface can validate connection parameters,
|
|
||||||
* test authentication, and verify service availability before creating a
|
|
||||||
* persistent service configuration.
|
|
||||||
*
|
|
||||||
* Supports two testing modes:
|
|
||||||
* 1. Testing an existing service (validate current configuration)
|
|
||||||
* 2. Testing a fresh configuration (validate before saving)
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
interface ProviderServiceTestInterface {
|
interface ProviderServiceTestInterface {
|
||||||
|
|
||||||
|
public const CAPABILITY_SERVICE_TEST = 'ServiceTest';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test a service connection
|
* Test a service connection
|
||||||
*
|
*
|
||||||
* Tests connectivity, authentication, and capabilities of a service.
|
* Tests connectivity, authentication, and capabilities of a service
|
||||||
*
|
|
||||||
* For new services: use serviceFresh() to create a service, configure it with
|
|
||||||
* setters, then pass it to this method for testing before persisting.
|
|
||||||
*
|
|
||||||
* For existing services: fetch the service and pass it directly.
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
@@ -49,28 +39,8 @@ interface ProviderServiceTestInterface {
|
|||||||
*
|
*
|
||||||
* @return array Test results in the format:
|
* @return array Test results in the format:
|
||||||
* [
|
* [
|
||||||
* 'success' => bool,
|
* 'disposition' => 'Success' | 'Failure' | 'Warning',
|
||||||
* 'message' => 'Connection successful' | 'Error message',
|
* 'message' => 'Connection successful' | 'Error message',
|
||||||
* 'details' => [
|
|
||||||
* 'connected' => bool, // Socket/HTTP connection succeeded
|
|
||||||
* 'authenticated' => bool, // Authentication succeeded
|
|
||||||
* 'capabilities' => ['IMAP4rev1', ...], // Server capabilities (if applicable)
|
|
||||||
* 'serverInfo' => 'Server version/banner',
|
|
||||||
* 'latency' => 123, // Connection time in milliseconds
|
|
||||||
* 'protocols' => [
|
|
||||||
* 'inbound' => [
|
|
||||||
* 'connected' => bool,
|
|
||||||
* 'authenticated' => bool,
|
|
||||||
* 'error' => 'error message if failed'
|
|
||||||
* ],
|
|
||||||
* 'outbound' => [ // For split-socket (IMAP+SMTP)
|
|
||||||
* 'connected' => bool,
|
|
||||||
* 'authenticated' => bool,
|
|
||||||
* 'error' => 'error message if failed'
|
|
||||||
* ]
|
|
||||||
* ],
|
|
||||||
* 'errors' => ['Error 1', 'Error 2'], // List of errors encountered
|
|
||||||
* ]
|
|
||||||
* ]
|
* ]
|
||||||
*/
|
*/
|
||||||
public function serviceTest(ServiceBaseInterface|ServiceMutableInterface $service, array $options = []): array;
|
public function serviceTest(ServiceBaseInterface|ServiceMutableInterface $service, array $options = []): array;
|
||||||
|
|||||||
@@ -11,19 +11,21 @@ namespace KTXF\Mail\Service;
|
|||||||
|
|
||||||
use Generator;
|
use Generator;
|
||||||
use KTXF\Mail\Collection\CollectionBaseInterface;
|
use KTXF\Mail\Collection\CollectionBaseInterface;
|
||||||
|
use KTXF\Mail\Entity\EntityBaseInterface;
|
||||||
use KTXF\Mail\Object\AddressInterface;
|
use KTXF\Mail\Object\AddressInterface;
|
||||||
|
use KTXF\Resource\BinaryResource;
|
||||||
use KTXF\Resource\Delta\Delta;
|
use KTXF\Resource\Delta\Delta;
|
||||||
use KTXF\Resource\Filter\IFilter;
|
use KTXF\Resource\Filter\IFilter;
|
||||||
|
use KTXF\Resource\Identifier\EntityIdentifierInterface;
|
||||||
use KTXF\Resource\Provider\ResourceServiceBaseInterface;
|
use KTXF\Resource\Provider\ResourceServiceBaseInterface;
|
||||||
use KTXF\Resource\Range\IRange;
|
use KTXF\Resource\Range\IRange;
|
||||||
use KTXF\Resource\Range\RangeType;
|
use KTXF\Resource\Range\RangeType;
|
||||||
use KTXF\Resource\Sort\ISort;
|
use KTXF\Resource\Sort\ISort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mail Service Base Interface
|
* Service Base Interface
|
||||||
*
|
*
|
||||||
* Core interface for mail services with full protocol support (IMAP, JMAP, EWS, ActiveSync, Gmail API, etc.)
|
* Minimum interface for a service, providing read-only access to collections and entities.
|
||||||
* Provides identity, addressing, capability information, and collection/message operations.
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
@@ -70,9 +72,9 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
public const CAPABILITY_ENTITY_SORT_DATE_SENT = 'sent';
|
public const CAPABILITY_ENTITY_SORT_DATE_SENT = 'sent';
|
||||||
public const CAPABILITY_ENTITY_SORT_SIZE = 'size';
|
public const CAPABILITY_ENTITY_SORT_SIZE = 'size';
|
||||||
|
|
||||||
public const JSON_TYPE = 'mail.service';
|
public const JSON_TYPE = 'mail:service';
|
||||||
public const JSON_PROPERTY_PRIMARY_ADDRESS = 'primaryAddress';
|
public const PROPERTY_PRIMARY_ADDRESS = 'primaryAddress';
|
||||||
public const JSON_PROPERTY_SECONDARY_ADDRESSES = 'secondaryAddresses';
|
public const PROPERTY_SECONDARY_ADDRESSES = 'secondaryAddresses';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the primary mailing address for this service
|
* Gets the primary mailing address for this service
|
||||||
@@ -111,7 +113,7 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
* @param IFilter|null $filter Optional filter criteria
|
* @param IFilter|null $filter Optional filter criteria
|
||||||
* @param ISort|null $sort Optional sort order
|
* @param ISort|null $sort Optional sort order
|
||||||
*
|
*
|
||||||
* @return array<string|int,CollectionBaseInterface> Collections indexed by ID
|
* @return array<string|int,CollectionBaseInterface> Collections indexed by identifier
|
||||||
*/
|
*/
|
||||||
public function collectionList(string|int $location, ?IFilter $filter = null, ?ISort $sort = null): array;
|
public function collectionList(string|int $location, ?IFilter $filter = null, ?ISort $sort = null): array;
|
||||||
|
|
||||||
@@ -138,9 +140,9 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int ...$identifiers Collection IDs to check
|
* @param string|int ...$identifiers Collection identifiers to check
|
||||||
*
|
*
|
||||||
* @return array<string|int,bool> Map of ID => exists
|
* @return array<string|int,bool> Map of identifier => exists
|
||||||
*/
|
*/
|
||||||
public function collectionExtant(string|int $location, string|int ...$identifiers): array;
|
public function collectionExtant(string|int $location, string|int ...$identifiers): array;
|
||||||
|
|
||||||
@@ -149,44 +151,44 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $identifier Collection ID
|
* @param string|int $identifier Collection identifier
|
||||||
*
|
*
|
||||||
* @return CollectionBaseInterface|null Collection or null if not found
|
* @return CollectionBaseInterface|null Collection or null if not found
|
||||||
*/
|
*/
|
||||||
public function collectionFetch(string|int $identifier): ?CollectionBaseInterface;
|
public function collectionFetch(string|int $identifier): ?CollectionBaseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists messages in a collection
|
* Lists entities in a collection
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection Collection ID
|
* @param string|int $collection Collection identifier
|
||||||
* @param IFilter|null $filter Optional filter criteria
|
* @param IFilter|null $filter Optional filter criteria
|
||||||
* @param ISort|null $sort Optional sort order
|
* @param ISort|null $sort Optional sort order
|
||||||
* @param IRange|null $range Optional pagination
|
* @param IRange|null $range Optional pagination
|
||||||
* @param array|null $properties Optional message properties to fetch
|
* @param array|null $properties Optional entity properties to fetch
|
||||||
*
|
*
|
||||||
* @return array<string|int,EntityBaseInterface> Messages indexed by ID
|
* @return array<string,EntityBaseInterface> Entities indexed by Urn
|
||||||
*/
|
*/
|
||||||
public function entityList(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array;
|
public function entityListBulk(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists messages in a collection
|
* Lists entities in a collection
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection Collection ID
|
* @param string|int $collection Collection identifier
|
||||||
* @param IFilter|null $filter Optional filter criteria
|
* @param IFilter|null $filter Optional filter criteria
|
||||||
* @param ISort|null $sort Optional sort order
|
* @param ISort|null $sort Optional sort order
|
||||||
* @param IRange|null $range Optional pagination
|
* @param IRange|null $range Optional pagination
|
||||||
* @param array|null $properties Optional message properties to fetch
|
* @param array|null $properties Optional entity properties to fetch
|
||||||
*
|
*
|
||||||
* @return Generator Yields messages one by one as EntityBaseInterface
|
* @return Generator Yields entities one by one as EntityBaseInterface
|
||||||
*/
|
*/
|
||||||
public function entityListStream(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): Generator;
|
public function entityListStream(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): Generator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a filter builder for messages
|
* Creates a filter builder for entities
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
@@ -195,7 +197,7 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
public function entityListFilter(): IFilter;
|
public function entityListFilter(): IFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a sort builder for messages
|
* Creates a sort builder for entities
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
@@ -204,7 +206,7 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
public function entityListSort(): ISort;
|
public function entityListSort(): ISort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a range builder for messages
|
* Creates a range builder for entities
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
@@ -215,40 +217,60 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
|
|||||||
public function entityListRange(RangeType $type): IRange;
|
public function entityListRange(RangeType $type): IRange;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets incremental changes since last sync
|
* Gets incremental changes since last signature
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection Collection ID
|
* @param string|int $collection Collection identifier
|
||||||
* @param string $signature Sync token from previous sync
|
* @param string $signature Token from previous delta
|
||||||
* @param string $detail Detail level: 'ids', 'minimal', 'full'
|
|
||||||
*
|
*
|
||||||
* @return array ['signature' => string, 'added' => array, 'modified' => array, 'removed' => array]
|
* @return array ['signature' => string, 'added' => array, 'modified' => array, 'removed' => array]
|
||||||
*/
|
*/
|
||||||
public function entityDelta(string|int $collection, string $signature, string $detail = 'ids'): Delta;
|
public function entityDelta(string|int $collection, string $signature): Delta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if messages exist
|
* Checks if entities exist
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection Collection ID
|
* @param string|int $collection Collection identifier
|
||||||
* @param string|int ...$identifiers Message IDs to check
|
* @param string|int ...$identifiers Entity identifiers to check
|
||||||
*
|
*
|
||||||
* @return array<string|int,bool> Map of ID => exists
|
* @return array<string|int,bool> Map of identifier => exists
|
||||||
*/
|
*/
|
||||||
public function entityExtant(string|int $collection, string|int ...$identifiers): array;
|
public function entityExtant(string|int $collection, string|int ...$identifiers): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches one or more entities
|
* Fetches one or more entities as an array
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*
|
*
|
||||||
* @param string|int $collection Collection ID
|
* @param EntityIdentifierInterface ...$identifiers Entity identifiers to fetch
|
||||||
* @param string|int ...$identifiers Message IDs to fetch
|
|
||||||
*
|
*
|
||||||
* @return array<string|int,EntityBaseInterface> Messages indexed by ID
|
* @return array<string,EntityBaseInterface> Entities indexed by Urn
|
||||||
*/
|
*/
|
||||||
public function entityFetch(string|int $collection, string|int ...$identifiers): array;
|
public function entityFetchBulk(EntityIdentifierInterface ...$identifiers): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches one or more entities as a stream
|
||||||
|
*
|
||||||
|
* @since 2025.05.01
|
||||||
|
*
|
||||||
|
* @param EntityIdentifierInterface ...$identifiers Entity identifiers to fetch
|
||||||
|
*
|
||||||
|
* @return Generator<string,EntityBaseInterface> Yields entities one by one
|
||||||
|
*/
|
||||||
|
public function entityFetchStream(EntityIdentifierInterface ...$identifiers): Generator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads an entity or part of an entity
|
||||||
|
*
|
||||||
|
* @since 2025.05.01
|
||||||
|
*
|
||||||
|
* @param EntityIdentifierInterface $target Entity identifier
|
||||||
|
* @param array|null $part Optional part to download
|
||||||
|
*
|
||||||
|
* @return BinaryResource
|
||||||
|
*/
|
||||||
|
public function entityDownload(EntityIdentifierInterface $target, array|null $part): BinaryResource;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,9 @@ use KTXF\Mail\Collection\CollectionPropertiesBaseInterface;
|
|||||||
use KTXF\Resource\Identifier\CollectionIdentifier;
|
use KTXF\Resource\Identifier\CollectionIdentifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mail Service Collection Mutable Interface
|
* Service Collection Mutable Interface
|
||||||
*
|
*
|
||||||
* Optional interface for services that support collection CRUD operations.
|
* Optional interface for services that support collection CRUD operations
|
||||||
* Provides mailbox/folder creation, modification, deletion, and moving.
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -12,10 +12,9 @@ namespace KTXF\Mail\Service;
|
|||||||
use KTXF\Resource\Provider\ResourceServiceConfigureInterface;
|
use KTXF\Resource\Provider\ResourceServiceConfigureInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mail Service Configurable Interface
|
* Service Configurable Interface
|
||||||
*
|
*
|
||||||
* Extends base service interface with setter methods for mutable properties.
|
* Extends base service interface with setter methods for mutable properties
|
||||||
* Used for service configuration and updates.
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,10 +16,9 @@ use KTXF\Resource\Identifier\CollectionIdentifier;
|
|||||||
use KTXF\Resource\Identifier\EntityIdentifier;
|
use KTXF\Resource\Identifier\EntityIdentifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mail Service Entity Mutable Interface
|
* Service Entity Mutable Interface
|
||||||
*
|
*
|
||||||
* Optional interface for services that support entity CRUD operations.
|
* Optional interface for services that support entity CRUD operations
|
||||||
* Provides entity creation, modification, deletion, copying, moving, and flag management.
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
@@ -66,6 +65,20 @@ interface ServiceEntityMutableInterface {
|
|||||||
*/
|
*/
|
||||||
public function entityModify(EntityIdentifier $target, MessagePropertiesMutableInterface $properties): EntityBaseInterface;
|
public function entityModify(EntityIdentifier $target, MessagePropertiesMutableInterface $properties): EntityBaseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patches an existing entity(ies) with partial data
|
||||||
|
*
|
||||||
|
* @since 2025.05.01
|
||||||
|
*
|
||||||
|
* @param MessagePropertiesMutableInterface $properties Partial entity properties
|
||||||
|
* @param EntityIdentifier ...$targets Source entities to patch
|
||||||
|
*
|
||||||
|
* @return array<string, array{
|
||||||
|
* disposition: 'patched'|'error'
|
||||||
|
* }> Results keyed by source entity identifier
|
||||||
|
*/
|
||||||
|
public function entityPatch(MessagePropertiesMutableInterface $properties, EntityIdentifier ...$targets): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes entities
|
* Deletes entities
|
||||||
*
|
*
|
||||||
@@ -81,20 +94,6 @@ interface ServiceEntityMutableInterface {
|
|||||||
*/
|
*/
|
||||||
public function entityDelete(EntityIdentifier ...$targets): array;
|
public function entityDelete(EntityIdentifier ...$targets): array;
|
||||||
|
|
||||||
/**
|
|
||||||
* Patches an existing entity(ies) with partial data
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @param MessagePropertiesMutableInterface $properties Partial entity properties
|
|
||||||
* @param EntityIdentifier ...$targets Source entities to patch
|
|
||||||
*
|
|
||||||
* @return array<string, array{
|
|
||||||
* disposition: 'patched'|'error'
|
|
||||||
* }> Results keyed by source entity identifier
|
|
||||||
*/
|
|
||||||
public function entityPatch(MessagePropertiesMutableInterface $properties, EntityIdentifier ...$targets): array;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves entities to another collection
|
* Moves entities to another collection
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace KTXF\Mail\Service;
|
||||||
|
|
||||||
|
use KTXF\Mail\Entity\EntityMutableInterface;
|
||||||
|
use KTXF\Mail\Object\AddressInterface;
|
||||||
|
use KTXF\Mail\Object\MessagePropertiesMutableInterface;
|
||||||
|
use KTXF\Mail\Submission\EntitySubmitResult;
|
||||||
|
use KTXF\Resource\Identifier\EntityIdentifierInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mail Service Submit Interface
|
||||||
|
*
|
||||||
|
* Interface for mail services capable of outbound submission.
|
||||||
|
* Supports submission of fresh in-memory messages and already-existing
|
||||||
|
* provider-backed drafts through a single provider-agnostic contract.
|
||||||
|
*
|
||||||
|
* @since 2026.06.07
|
||||||
|
*/
|
||||||
|
interface ServiceEntitySubmitInterface {
|
||||||
|
|
||||||
|
public const CAPABILITY_ENTITY_SUBMIT_FRESH = 'EntitySubmitFresh';
|
||||||
|
public const CAPABILITY_ENTITY_SUBMIT_DRAFT = 'EntitySubmitDraft';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a fresh entity instance for composition
|
||||||
|
*
|
||||||
|
* @since 2025.05.01
|
||||||
|
*
|
||||||
|
* @return EntityMutableInterface Fresh entity object
|
||||||
|
*/
|
||||||
|
public function entityFresh(): EntityMutableInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submits an outbound message.
|
||||||
|
*
|
||||||
|
* @since 2026.06.07
|
||||||
|
*
|
||||||
|
* @param AddressInterface $sender Sender address
|
||||||
|
* @param EntityIdentifierInterface|null $source Source entity identifier
|
||||||
|
* @param MessagePropertiesMutableInterface|null $message Message properties
|
||||||
|
*
|
||||||
|
* @return EntitySubmitResult Normalized submission result
|
||||||
|
*/
|
||||||
|
public function entitySubmit(AddressInterface $sender, EntityIdentifierInterface|null $source = null, MessagePropertiesMutableInterface|null $message = null): EntitySubmitResult;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace KTXF\Mail\Service;
|
|
||||||
|
|
||||||
use KTXF\Mail\Entity\EntityMutableInterface;
|
|
||||||
use KTXF\Mail\Exception\SendException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mail Service Transmit Interface
|
|
||||||
*
|
|
||||||
* Interface for mail services capable of transmitting outbound entities.
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*/
|
|
||||||
interface ServiceEntityTransmitInterface {
|
|
||||||
|
|
||||||
public const CAPABILITY_ENTITY_TRANSMIT = 'EntityTransmit';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a fresh entity instance for composition
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @return EntityMutableInterface Fresh entity object
|
|
||||||
*/
|
|
||||||
public function entityFresh(): EntityMutableInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transmits an outbound entity
|
|
||||||
*
|
|
||||||
* @since 2025.05.01
|
|
||||||
*
|
|
||||||
* @param EntityMutableInterface $entity Entity to transmit
|
|
||||||
*
|
|
||||||
* @return string Entity identifier assigned by the transport
|
|
||||||
*
|
|
||||||
* @throws SendException On delivery failure
|
|
||||||
*/
|
|
||||||
public function entitySend(EntityMutableInterface $entity): string;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -13,10 +13,9 @@ use KTXF\Mail\Object\AddressInterface;
|
|||||||
use KTXF\Resource\Provider\ResourceServiceMutateInterface;
|
use KTXF\Resource\Provider\ResourceServiceMutateInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mail Service Mutable Interface
|
* Service Mutable Interface
|
||||||
*
|
*
|
||||||
* Extends base service interface with setter methods for mutable properties.
|
* Extends base service interface with setter methods for mutable properties
|
||||||
* Used for service configuration and updates.
|
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace KTXF\Mail\Submission;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use JsonSerializable;
|
||||||
|
use KTXF\Resource\Identifier\EntityIdentifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity Submit Result
|
||||||
|
*
|
||||||
|
* Normalized result for outbound submission.
|
||||||
|
*
|
||||||
|
* @since 2026.06.07
|
||||||
|
*/
|
||||||
|
final class EntitySubmitResult implements JsonSerializable {
|
||||||
|
|
||||||
|
public const DISPOSITION_SENT = 'sent';
|
||||||
|
public const DISPOSITION_ERROR = 'error';
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
public readonly string $disposition,
|
||||||
|
public readonly ?string $transportId = null,
|
||||||
|
public readonly ?EntityIdentifier $sourceDraft = null,
|
||||||
|
public readonly ?EntityIdentifier $sentEntity = null,
|
||||||
|
public readonly ?string $errorCode = null,
|
||||||
|
public readonly ?string $errorMessage = null,
|
||||||
|
) {
|
||||||
|
if (!in_array($this->disposition, [self::DISPOSITION_SENT, self::DISPOSITION_ERROR], true)) {
|
||||||
|
throw new InvalidArgumentException('Invalid submission disposition: ' . $this->disposition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function jsonSerialize(): array {
|
||||||
|
return array_filter([
|
||||||
|
'disposition' => $this->disposition,
|
||||||
|
'transportId' => $this->transportId,
|
||||||
|
'sourceDraft' => $this->sourceDraft !== null ? (string)$this->sourceDraft : null,
|
||||||
|
'sentEntity' => $this->sentEntity !== null ? (string)$this->sentEntity : null,
|
||||||
|
'errorCode' => $this->errorCode,
|
||||||
|
'errorMessage' => $this->errorMessage,
|
||||||
|
], static fn(mixed $value): bool => $value !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -41,7 +41,7 @@ abstract class CollectionMutableAbstract extends NodeMutableAbstract implements
|
|||||||
// Copy all property values
|
// Copy all property values
|
||||||
$this->properties->setLabel($value->getLabel());
|
$this->properties->setLabel($value->getLabel());
|
||||||
$this->properties->setDescription($value->getDescription());
|
$this->properties->setDescription($value->getDescription());
|
||||||
$this->properties->setPriority($value->getPriority());
|
$this->properties->setRank($value->getRank());
|
||||||
$this->properties->setVisibility($value->getVisibility());
|
$this->properties->setVisibility($value->getVisibility());
|
||||||
$this->properties->setColor($value->getColor());
|
$this->properties->setColor($value->getColor());
|
||||||
|
|
||||||
|
|||||||
@@ -20,17 +20,15 @@ use KTXF\Resource\Provider\Node\NodePropertiesBaseAbstract;
|
|||||||
*/
|
*/
|
||||||
abstract class CollectionPropertiesBaseAbstract extends NodePropertiesBaseAbstract implements CollectionPropertiesBaseInterface {
|
abstract class CollectionPropertiesBaseAbstract extends NodePropertiesBaseAbstract implements CollectionPropertiesBaseInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = CollectionPropertiesBaseInterface::JSON_TYPE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function content(): array {
|
public function content(): array {
|
||||||
$content = $this->data[self::JSON_PROPERTY_CONTENT] ?? null;
|
$content = $this->data[self::PROPERTY_CONTENT] ?? null;
|
||||||
if (is_array($content)) {
|
if (is_array($content)) {
|
||||||
return array_map(function ($item) {
|
return array_filter(array_map(function ($item) {
|
||||||
return new CollectionContent($item);
|
return $item instanceof CollectionContent ? $item : CollectionContent::tryFrom($item);
|
||||||
}, $content);
|
}, $content));
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -40,35 +38,35 @@ abstract class CollectionPropertiesBaseAbstract extends NodePropertiesBaseAbstra
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getLabel(): string {
|
public function getLabel(): string {
|
||||||
return $this->data[self::JSON_PROPERTY_LABEL] ?? '';
|
return $this->data[self::PROPERTY_LABEL] ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getDescription(): ?string {
|
public function getDescription(): ?string {
|
||||||
return $this->data[self::JSON_PROPERTY_DESCRIPTION] ?? null;
|
return $this->data[self::PROPERTY_DESCRIPTION] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getPriority(): ?int {
|
public function getRank(): ?int {
|
||||||
return $this->data[self::JSON_PROPERTY_PRIORITY] ?? null;
|
return $this->data[self::PROPERTY_RANK] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getVisibility(): ?bool {
|
public function getVisibility(): ?bool {
|
||||||
return $this->data[self::JSON_PROPERTY_VISIBILITY] ?? null;
|
return $this->data[self::PROPERTY_VISIBILITY] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getColor(): ?string {
|
public function getColor(): ?string {
|
||||||
return $this->data[self::JSON_PROPERTY_COLOR] ?? null;
|
return $this->data[self::PROPERTY_COLOR] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,18 +10,17 @@ declare(strict_types=1);
|
|||||||
namespace KTXF\People\Collection;
|
namespace KTXF\People\Collection;
|
||||||
|
|
||||||
use KTXF\Resource\Provider\Node\NodePropertiesBaseInterface;
|
use KTXF\Resource\Provider\Node\NodePropertiesBaseInterface;
|
||||||
use PhpParser\Node\Expr\Array_;
|
|
||||||
|
|
||||||
interface CollectionPropertiesBaseInterface extends NodePropertiesBaseInterface {
|
interface CollectionPropertiesBaseInterface extends NodePropertiesBaseInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = 'people:collection';
|
public const JSON_TYPE = 'people:collection';
|
||||||
public const JSON_PROPERTY_CONTENT = 'content';
|
public const PROPERTY_CONTENT = 'content';
|
||||||
|
|
||||||
public const JSON_PROPERTY_LABEL = 'label';
|
public const PROPERTY_LABEL = 'label';
|
||||||
public const JSON_PROPERTY_DESCRIPTION = 'description';
|
public const PROPERTY_DESCRIPTION = 'description';
|
||||||
public const JSON_PROPERTY_PRIORITY = 'priority';
|
public const PROPERTY_RANK = 'rank';
|
||||||
public const JSON_PROPERTY_VISIBILITY = 'visibility';
|
public const PROPERTY_VISIBILITY = 'visibility';
|
||||||
public const JSON_PROPERTY_COLOR = 'color';
|
public const PROPERTY_COLOR = 'color';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the content type of this collection
|
* Gets the content type of this collection
|
||||||
@@ -47,11 +46,11 @@ interface CollectionPropertiesBaseInterface extends NodePropertiesBaseInterface
|
|||||||
public function getDescription(): ?string;
|
public function getDescription(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the priority of this collection
|
* Gets the rank of this collection
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
public function getPriority(): ?int;
|
public function getRank(): ?int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the visibility of this collection
|
* Gets the visibility of this collection
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ abstract class CollectionPropertiesMutableAbstract extends CollectionPropertiesB
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setLabel(string $value): static {
|
public function setLabel(string $value): static {
|
||||||
$this->data[self::JSON_PROPERTY_LABEL] = $value;
|
$this->data[self::PROPERTY_LABEL] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,15 +41,15 @@ abstract class CollectionPropertiesMutableAbstract extends CollectionPropertiesB
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setDescription(?string $value): static {
|
public function setDescription(?string $value): static {
|
||||||
$this->data[self::JSON_PROPERTY_DESCRIPTION] = $value;
|
$this->data[self::PROPERTY_DESCRIPTION] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setPriority(?int $value): static {
|
public function setRank(?int $value): static {
|
||||||
$this->data[self::JSON_PROPERTY_PRIORITY] = $value;
|
$this->data[self::PROPERTY_RANK] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ abstract class CollectionPropertiesMutableAbstract extends CollectionPropertiesB
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setVisibility(?bool $value): static {
|
public function setVisibility(?bool $value): static {
|
||||||
$this->data[self::JSON_PROPERTY_VISIBILITY] = $value;
|
$this->data[self::PROPERTY_VISIBILITY] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ abstract class CollectionPropertiesMutableAbstract extends CollectionPropertiesB
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function setColor(?string $value): static {
|
public function setColor(?string $value): static {
|
||||||
$this->data[self::JSON_PROPERTY_COLOR] = $value;
|
$this->data[self::PROPERTY_COLOR] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,11 +30,11 @@ interface CollectionPropertiesMutableInterface extends NodePropertiesMutableInte
|
|||||||
public function setDescription(?string $value): static;
|
public function setDescription(?string $value): static;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the priority of this collection
|
* Sets the rank of this collection
|
||||||
*
|
*
|
||||||
* @since 2025.05.01
|
* @since 2025.05.01
|
||||||
*/
|
*/
|
||||||
public function setPriority(?int $value): static;
|
public function setRank(?int $value): static;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the visibility of this collection
|
* Sets the visibility of this collection
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace KTXF\People\Entity;
|
namespace KTXF\People\Entity;
|
||||||
|
|
||||||
|
use KTXF\Resource\Identifier\EntityIdentifier;
|
||||||
use KTXF\Resource\Provider\Node\NodeBaseAbstract;
|
use KTXF\Resource\Provider\Node\NodeBaseAbstract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,7 +21,12 @@ use KTXF\Resource\Provider\Node\NodeBaseAbstract;
|
|||||||
*/
|
*/
|
||||||
abstract class EntityBaseAbstract extends NodeBaseAbstract implements EntityBaseInterface {
|
abstract class EntityBaseAbstract extends NodeBaseAbstract implements EntityBaseInterface {
|
||||||
|
|
||||||
protected EntityPropertiesBaseAbstract $properties;
|
protected string $type = 'people:entity';
|
||||||
|
protected EntityPropertiesBaseInterface $properties;
|
||||||
|
|
||||||
|
protected function nodeIdentifier(): EntityIdentifier {
|
||||||
|
return new EntityIdentifier($this->data[static::PROPERTY_PROVIDER], $this->data[static::PROPERTY_SERVICE], $this->data[static::PROPERTY_COLLECTION], $this->data[static::PROPERTY_IDENTIFIER]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ use KTXF\Resource\Provider\Node\NodeBaseInterface;
|
|||||||
|
|
||||||
interface EntityBaseInterface extends NodeBaseInterface {
|
interface EntityBaseInterface extends NodeBaseInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = 'people:entity';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the entity properties
|
* Gets the entity properties
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace KTXF\People\Entity;
|
namespace KTXF\People\Entity;
|
||||||
|
|
||||||
|
use KTXF\Resource\Identifier\EntityIdentifier;
|
||||||
use KTXF\Resource\Provider\Node\NodeMutableAbstract;
|
use KTXF\Resource\Provider\Node\NodeMutableAbstract;
|
||||||
use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface;
|
use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface;
|
||||||
|
|
||||||
@@ -21,9 +22,12 @@ use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface;
|
|||||||
*/
|
*/
|
||||||
abstract class EntityMutableAbstract extends NodeMutableAbstract implements EntityMutableInterface {
|
abstract class EntityMutableAbstract extends NodeMutableAbstract implements EntityMutableInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = EntityMutableInterface::JSON_TYPE;
|
protected string $type = 'people:entity';
|
||||||
|
protected EntityPropertiesMutableInterface $properties;
|
||||||
|
|
||||||
protected EntityPropertiesMutableAbstract $properties;
|
protected function nodeIdentifier(): EntityIdentifier {
|
||||||
|
return new EntityIdentifier($this->data[static::PROPERTY_PROVIDER], $this->data[static::PROPERTY_SERVICE], (string) $this->data[static::PROPERTY_COLLECTION], (string) $this->data[static::PROPERTY_IDENTIFIER]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
@@ -40,7 +44,7 @@ abstract class EntityMutableAbstract extends NodeMutableAbstract implements Enti
|
|||||||
throw new \InvalidArgumentException('Properties must implement EntityPropertiesMutableInterface');
|
throw new \InvalidArgumentException('Properties must implement EntityPropertiesMutableInterface');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->properties->setDataRaw($value->getDataRaw());
|
$this->properties = $value;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ use KTXF\Resource\Provider\Node\NodeMutableInterface;
|
|||||||
*/
|
*/
|
||||||
interface EntityMutableInterface extends EntityBaseInterface, NodeMutableInterface {
|
interface EntityMutableInterface extends EntityBaseInterface, NodeMutableInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = EntityBaseInterface::JSON_TYPE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the entity properties (mutable)
|
* Gets the entity properties (mutable)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ use KTXF\Resource\Provider\Node\NodePropertiesBaseAbstract;
|
|||||||
|
|
||||||
abstract class EntityPropertiesBaseAbstract extends NodePropertiesBaseAbstract implements EntityPropertiesBaseInterface {
|
abstract class EntityPropertiesBaseAbstract extends NodePropertiesBaseAbstract implements EntityPropertiesBaseInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = EntityPropertiesBaseInterface::JSON_TYPE;
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public function getDataRaw(): array|string|null {
|
public function getDataRaw(): array|string|null {
|
||||||
return $this->data[self::JSON_PROPERTY_DATA] ?? null;
|
return $this->data[self::PROPERTY_DATA] ?? null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use KTXF\Resource\Provider\Node\NodePropertiesBaseInterface;
|
|||||||
interface EntityPropertiesBaseInterface extends NodePropertiesBaseInterface {
|
interface EntityPropertiesBaseInterface extends NodePropertiesBaseInterface {
|
||||||
|
|
||||||
public const JSON_TYPE = 'people:entity';
|
public const JSON_TYPE = 'people:entity';
|
||||||
public const JSON_PROPERTY_DATA = 'data';
|
public const PROPERTY_DATA = 'data';
|
||||||
|
|
||||||
public function getDataRaw(): array|string|null;
|
public function getDataRaw(): array|string|null;
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user