diff --git a/.gitmodules b/.gitmodules
index 246626547..7ebe00a4d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,24 +2,30 @@
path = gn
url = https://github.com/gradido/gn.git
branch = master
-#[submodule "mithril_client"]
-# path = community_server/mithril_client
-# url = https://github.com/gradido/gradido_mithrilJS_client.git
-[submodule "src/protobuf"]
- path = community_server/src/protobuf
- url = https://github.com/gradido/gradido_protocol.git
-[submodule "dependencies/tinf"]
- path = login_server/dependencies/tinf
- url = https://github.com/jibsen/tinf.git
-[submodule "dependencies/mariadb-connector-c"]
- path = login_server/dependencies/mariadb-connector-c
- url = https://github.com/MariaDB/mariadb-connector-c.git
-[submodule "src/proto"]
- path = login_server/src/proto
- url = https://github.com/gradido/gradido_protocol.git
-[submodule "dependencies/iroha-ed25519"]
- path = login_server/dependencies/iroha-ed25519
- url = https://github.com/gradido/iroha-ed25519.git
-[submodule "dependencies/spirit-po"]
- path = login_server/dependencies/spirit-po
- url = https://github.com/cbeck88/spirit-po.git
\ No newline at end of file
+
+[submodule "login_server/dependencies/tinf"]
+ path = login_server/dependencies/tinf
+ url = https://github.com/jibsen/tinf.git
+[submodule "login_server/dependencies/mariadb-connector-c"]
+ path = login_server/dependencies/mariadb-connector-c
+ url = https://github.com/MariaDB/mariadb-connector-c.git
+[submodule "login_server/src/proto"]
+ path = login_server/src/proto
+ url = https://github.com/gradido/gradido_protocol.git
+[submodule "login_server/dependencies/spirit-po"]
+ path = login_server/dependencies/spirit-po
+ url = https://github.com/cbeck88/spirit-po.git
+[submodule "login_server/dependencies/grpc"]
+ path = login_server/dependencies/grpc
+ url = https://github.com/grpc/grpc.git
+[submodule "login_server/dependencies/poco"]
+ path = login_server/dependencies/poco
+ url = https://github.com/pocoproject/poco.git
+[submodule "login_server/dependencies/cmake-modules"]
+ path = login_server/dependencies/cmake-modules
+ url = https://github.com/viaduck/cmake-modules.git
+
+[submodule "community_server/src/protobuf"]
+ path = community_server/src/protobuf
+ url = git@github.com:gradido/gradido_protocol.git
+
diff --git a/community_server/.gitignore b/community_server/.gitignore
index 4a3ce5c25..633978598 100644
--- a/community_server/.gitignore
+++ b/community_server/.gitignore
@@ -3,7 +3,6 @@ logs/
src/GPBMetadata/
tmp/
vendor/
-composer.lock
websrc/node_modules/
websrc/package-lock.json
mithril_client/
diff --git a/community_server/.gitmodules b/community_server/.gitmodules
index 9077bcecf..8499eaac6 100644
--- a/community_server/.gitmodules
+++ b/community_server/.gitmodules
@@ -1,6 +1,3 @@
-#[submodule "mithril_client"]
-# path = mithril_client
-# url = git@github.com:gradido/gradido_mithrilJS_client.git
[submodule "src/protobuf"]
path = src/protobuf
url = git@github.com:gradido/gradido_protocol.git
diff --git a/community_server/composer.json b/community_server/composer.json
index 784c6d123..4f9203bd4 100644
--- a/community_server/composer.json
+++ b/community_server/composer.json
@@ -6,7 +6,7 @@
"license": "MIT",
"require": {
"php": ">=5.6",
- "cakephp/cakephp": "3.8.*",
+ "cakephp/cakephp": "3.9.*",
"cakephp/migrations": "^2.0.0",
"cakephp/plugin-installer": "^1.0",
"datto/json-rpc": "^6.0",
@@ -30,9 +30,9 @@
"autoload": {
"psr-4": {
"App\\": "src/",
- "" : "src/",
- "GPBMetadata\\": "src/GPBMetadata",
- "Model\\Messages\\Gradido\\" : "src/Model/Messages/Gradido"
+ "" : "src/",
+ "GPBMetadata\\Gradido\\": "src/Model/Messages/GPBMetadata/Gradido/",
+ "Proto\\Gradido\\" : "src/Model/Messages/Proto/Gradido/"
}
},
"autoload-dev": {
diff --git a/community_server/composer.lock b/community_server/composer.lock
new file mode 100644
index 000000000..41674bb88
--- /dev/null
+++ b/community_server/composer.lock
@@ -0,0 +1,5577 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "8a3d1923190a6c9d6066359057844457",
+ "packages": [
+ {
+ "name": "aura/intl",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/auraphp/Aura.Intl.git",
+ "reference": "7fce228980b19bf4dee2d7bbd6202a69b0dde926"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/auraphp/Aura.Intl/zipball/7fce228980b19bf4dee2d7bbd6202a69b0dde926",
+ "reference": "7fce228980b19bf4dee2d7bbd6202a69b0dde926",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Aura\\Intl\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Aura.Intl Contributors",
+ "homepage": "https://github.com/auraphp/Aura.Intl/contributors"
+ }
+ ],
+ "description": "The Aura Intl package provides internationalization tools, specifically message translation.",
+ "homepage": "https://github.com/auraphp/Aura.Intl",
+ "keywords": [
+ "g11n",
+ "globalization",
+ "i18n",
+ "internationalization",
+ "intl",
+ "l10n",
+ "localization"
+ ],
+ "support": {
+ "issues": "https://github.com/auraphp/Aura.Intl/issues",
+ "source": "https://github.com/auraphp/Aura.Intl/tree/3.x"
+ },
+ "time": "2017-01-20T05:00:11+00:00"
+ },
+ {
+ "name": "cakephp/cakephp",
+ "version": "3.9.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cakephp/cakephp.git",
+ "reference": "b0e43e810132a8b1f66cf89b038b54c090811c32"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cakephp/cakephp/zipball/b0e43e810132a8b1f66cf89b038b54c090811c32",
+ "reference": "b0e43e810132a8b1f66cf89b038b54c090811c32",
+ "shasum": ""
+ },
+ "require": {
+ "aura/intl": "^3.0.0",
+ "cakephp/chronos": "^1.0.1",
+ "ext-intl": "*",
+ "ext-mbstring": "*",
+ "laminas/laminas-diactoros": "^1.4.0",
+ "paragonie/random_compat": "^1.4|^2.0|9.99.99",
+ "php": ">=5.6.0,<8.0.0",
+ "psr/log": "^1.0.0",
+ "psr/simple-cache": "^1.0.0"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<5.7"
+ },
+ "replace": {
+ "cakephp/cache": "self.version",
+ "cakephp/collection": "self.version",
+ "cakephp/core": "self.version",
+ "cakephp/database": "self.version",
+ "cakephp/datasource": "self.version",
+ "cakephp/event": "self.version",
+ "cakephp/filesystem": "self.version",
+ "cakephp/form": "self.version",
+ "cakephp/i18n": "self.version",
+ "cakephp/log": "self.version",
+ "cakephp/orm": "self.version",
+ "cakephp/utility": "self.version",
+ "cakephp/validation": "self.version"
+ },
+ "require-dev": {
+ "cakephp/cakephp-codesniffer": "^3.0",
+ "cakephp/chronos": "^1.2.1",
+ "paragonie/csp-builder": "^1.4|^2.3",
+ "phpunit/phpunit": "^5.7.14|^6.0"
+ },
+ "suggest": {
+ "ext-curl": "To enable more efficient network calls in Http\\Client.",
+ "ext-openssl": "To use Security::encrypt() or have secure CSRF token generation.",
+ "lib-ICU": "The intl PHP library, to use Text::transliterate() or Text::slug()",
+ "paragonie/csp-builder": "CSP builder, to use the CSP Middleware"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Cake\\": "src/"
+ },
+ "files": [
+ "src/Core/functions.php",
+ "src/Collection/functions.php",
+ "src/I18n/functions.php",
+ "src/Utility/bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "CakePHP Community",
+ "homepage": "https://github.com/cakephp/cakephp/graphs/contributors"
+ }
+ ],
+ "description": "The CakePHP framework",
+ "homepage": "https://cakephp.org",
+ "keywords": [
+ "conventions over configuration",
+ "dry",
+ "form",
+ "framework",
+ "mvc",
+ "orm",
+ "psr-7",
+ "rapid-development",
+ "validation"
+ ],
+ "support": {
+ "forum": "https://stackoverflow.com/tags/cakephp",
+ "irc": "irc://irc.freenode.org/cakephp",
+ "issues": "https://github.com/cakephp/cakephp/issues",
+ "source": "https://github.com/cakephp/cakephp"
+ },
+ "time": "2021-03-10T02:10:31+00:00"
+ },
+ {
+ "name": "cakephp/chronos",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cakephp/chronos.git",
+ "reference": "ba2bab98849e7bf29b02dd634ada49ab36472959"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cakephp/chronos/zipball/ba2bab98849e7bf29b02dd634ada49ab36472959",
+ "reference": "ba2bab98849e7bf29b02dd634ada49ab36472959",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1",
+ "cakephp/cakephp-codesniffer": "^3.0",
+ "phpbench/phpbench": "@dev",
+ "phpunit/phpunit": "<6.0 || ^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Cake\\Chronos\\": "src/"
+ },
+ "files": [
+ "src/carbon_compat.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Brian Nesbitt",
+ "email": "brian@nesbot.com",
+ "homepage": "http://nesbot.com"
+ },
+ {
+ "name": "The CakePHP Team",
+ "homepage": "http://cakephp.org"
+ }
+ ],
+ "description": "A simple API extension for DateTime.",
+ "homepage": "http://cakephp.org",
+ "keywords": [
+ "date",
+ "datetime",
+ "time"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/cakephp",
+ "issues": "https://github.com/cakephp/chronos/issues",
+ "source": "https://github.com/cakephp/chronos"
+ },
+ "time": "2019-11-30T02:33:19+00:00"
+ },
+ {
+ "name": "cakephp/migrations",
+ "version": "2.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cakephp/migrations.git",
+ "reference": "7fa4f1f8a4cd90df59cd8e3a46958c822abe457e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cakephp/migrations/zipball/7fa4f1f8a4cd90df59cd8e3a46958c822abe457e",
+ "reference": "7fa4f1f8a4cd90df59cd8e3a46958c822abe457e",
+ "shasum": ""
+ },
+ "require": {
+ "cakephp/cache": "^3.6.0",
+ "cakephp/orm": "^3.6.0",
+ "php": ">=5.6.0",
+ "robmorgan/phinx": "^0.10.3|^0.11.1"
+ },
+ "require-dev": {
+ "cakephp/bake": "^1.7.0",
+ "cakephp/cakephp": "^3.6.0",
+ "cakephp/cakephp-codesniffer": "^3.0",
+ "phpunit/phpunit": "^5.7.14|^6.0"
+ },
+ "suggest": {
+ "cakephp/bake": "If you want to generate migrations."
+ },
+ "type": "cakephp-plugin",
+ "autoload": {
+ "psr-4": {
+ "Migrations\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "CakePHP Community",
+ "homepage": "https://github.com/cakephp/migrations/graphs/contributors"
+ }
+ ],
+ "description": "Database Migration plugin for CakePHP based on Phinx",
+ "homepage": "https://github.com/cakephp/migrations",
+ "keywords": [
+ "cakephp",
+ "migrations"
+ ],
+ "support": {
+ "forum": "https://stackoverflow.com/tags/cakephp",
+ "irc": "irc://irc.freenode.org/cakephp",
+ "issues": "https://github.com/cakephp/migrations/issues",
+ "source": "https://github.com/cakephp/migrations"
+ },
+ "time": "2020-02-05T15:00:43+00:00"
+ },
+ {
+ "name": "cakephp/plugin-installer",
+ "version": "1.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cakephp/plugin-installer.git",
+ "reference": "e27027aa2d3d8ab64452c6817629558685a064cb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cakephp/plugin-installer/zipball/e27027aa2d3d8ab64452c6817629558685a064cb",
+ "reference": "e27027aa2d3d8ab64452c6817629558685a064cb",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0 || ^2.0",
+ "php": ">=5.6.0"
+ },
+ "require-dev": {
+ "cakephp/cakephp-codesniffer": "^3.3",
+ "composer/composer": "^2.0",
+ "phpunit/phpunit": "^5.7 || ^6.5 || ^8.5 || ^9.3"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "Cake\\Composer\\Plugin"
+ },
+ "autoload": {
+ "psr-4": {
+ "Cake\\Composer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "CakePHP Community",
+ "homepage": "https://cakephp.org"
+ }
+ ],
+ "description": "A composer installer for CakePHP 3.0+ plugins.",
+ "support": {
+ "issues": "https://github.com/cakephp/plugin-installer/issues",
+ "source": "https://github.com/cakephp/plugin-installer/tree/1.3.1"
+ },
+ "time": "2020-10-29T04:00:42+00:00"
+ },
+ {
+ "name": "datto/json-rpc",
+ "version": "6.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/datto/php-json-rpc.git",
+ "reference": "ad4d735f48d80c6b53f7405e5007d97c996533f6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/datto/php-json-rpc/zipball/ad4d735f48d80c6b53f7405e5007d97c996533f6",
+ "reference": "ad4d735f48d80c6b53f7405e5007d97c996533f6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Datto\\JsonRpc\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-3.0+"
+ ],
+ "authors": [
+ {
+ "name": "Spencer Mortensen",
+ "email": "smortensen@datto.com",
+ "homepage": "http://spencermortensen.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "Fully unit-tested JSON-RPC 2.0 for PHP",
+ "homepage": "http://datto.com",
+ "keywords": [
+ "json",
+ "json-rpc",
+ "jsonrpc",
+ "php",
+ "php-json-rpc",
+ "rpc"
+ ],
+ "support": {
+ "issues": "https://github.com/datto/php-json-rpc/issues",
+ "source": "https://github.com/datto/php-json-rpc/tree/6.1.0"
+ },
+ "time": "2020-02-28T23:54:06+00:00"
+ },
+ {
+ "name": "google/protobuf",
+ "version": "v3.10.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/protocolbuffers/protobuf-php.git",
+ "reference": "5dffdd2c84112e6c91fd84f92e3df96649426881"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/5dffdd2c84112e6c91fd84f92e3df96649426881",
+ "reference": "5dffdd2c84112e6c91fd84f92e3df96649426881",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": ">=4.8.0"
+ },
+ "suggest": {
+ "ext-bcmath": "Need to support JSON deserialization"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Google\\Protobuf\\": "src/Google/Protobuf",
+ "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "proto library for PHP",
+ "homepage": "https://developers.google.com/protocol-buffers/",
+ "keywords": [
+ "proto"
+ ],
+ "support": {
+ "issues": "https://github.com/protocolbuffers/protobuf-php/issues",
+ "source": "https://github.com/protocolbuffers/protobuf-php/tree/v3.10.0"
+ },
+ "time": "2019-10-03T20:08:37+00:00"
+ },
+ {
+ "name": "laminas/laminas-diactoros",
+ "version": "1.8.7p2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laminas/laminas-diactoros.git",
+ "reference": "6991c1af7c8d2c8efee81b22ba97024781824aaa"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6991c1af7c8d2c8efee81b22ba97024781824aaa",
+ "reference": "6991c1af7c8d2c8efee81b22ba97024781824aaa",
+ "shasum": ""
+ },
+ "require": {
+ "laminas/laminas-zendframework-bridge": "^1.0",
+ "php": "^5.6 || ^7.0",
+ "psr/http-message": "^1.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "replace": {
+ "zendframework/zend-diactoros": "~1.8.7.0"
+ },
+ "require-dev": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "laminas/laminas-coding-standard": "~1.0",
+ "php-http/psr7-integration-tests": "dev-master",
+ "phpunit/phpunit": "^5.7.16 || ^6.0.8 || ^7.2.7"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-release-1.8": "1.8.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions/create_uploaded_file.php",
+ "src/functions/marshal_headers_from_sapi.php",
+ "src/functions/marshal_method_from_sapi.php",
+ "src/functions/marshal_protocol_version_from_sapi.php",
+ "src/functions/marshal_uri_from_sapi.php",
+ "src/functions/normalize_server.php",
+ "src/functions/normalize_uploaded_files.php",
+ "src/functions/parse_cookie_header.php",
+ "src/functions/create_uploaded_file.legacy.php",
+ "src/functions/marshal_headers_from_sapi.legacy.php",
+ "src/functions/marshal_method_from_sapi.legacy.php",
+ "src/functions/marshal_protocol_version_from_sapi.legacy.php",
+ "src/functions/marshal_uri_from_sapi.legacy.php",
+ "src/functions/normalize_server.legacy.php",
+ "src/functions/normalize_uploaded_files.legacy.php",
+ "src/functions/parse_cookie_header.legacy.php"
+ ],
+ "psr-4": {
+ "Laminas\\Diactoros\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "PSR HTTP Message implementations",
+ "homepage": "https://laminas.dev",
+ "keywords": [
+ "http",
+ "laminas",
+ "psr",
+ "psr-7"
+ ],
+ "support": {
+ "chat": "https://laminas.dev/chat",
+ "docs": "https://docs.laminas.dev/laminas-diactoros/",
+ "forum": "https://discourse.laminas.dev",
+ "issues": "https://github.com/laminas/laminas-diactoros/issues",
+ "rss": "https://github.com/laminas/laminas-diactoros/releases.atom",
+ "source": "https://github.com/laminas/laminas-diactoros"
+ },
+ "time": "2020-03-23T15:28:28+00:00"
+ },
+ {
+ "name": "laminas/laminas-zendframework-bridge",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laminas/laminas-zendframework-bridge.git",
+ "reference": "6ede70583e101030bcace4dcddd648f760ddf642"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6ede70583e101030bcace4dcddd648f760ddf642",
+ "reference": "6ede70583e101030bcace4dcddd648f760ddf642",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3",
+ "squizlabs/php_codesniffer": "^3.5"
+ },
+ "type": "library",
+ "extra": {
+ "laminas": {
+ "module": "Laminas\\ZendFrameworkBridge"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/autoload.php"
+ ],
+ "psr-4": {
+ "Laminas\\ZendFrameworkBridge\\": "src//"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "Alias legacy ZF class names to Laminas Project equivalents.",
+ "keywords": [
+ "ZendFramework",
+ "autoloading",
+ "laminas",
+ "zf"
+ ],
+ "support": {
+ "forum": "https://discourse.laminas.dev/",
+ "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues",
+ "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom",
+ "source": "https://github.com/laminas/laminas-zendframework-bridge"
+ },
+ "funding": [
+ {
+ "url": "https://funding.communitybridge.org/projects/laminas-project",
+ "type": "community_bridge"
+ }
+ ],
+ "time": "2020-09-14T14:23:00+00:00"
+ },
+ {
+ "name": "mobiledetect/mobiledetectlib",
+ "version": "2.8.37",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/serbanghita/Mobile-Detect.git",
+ "reference": "9841e3c46f5bd0739b53aed8ac677fa712943df7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/9841e3c46f5bd0739b53aed8ac677fa712943df7",
+ "reference": "9841e3c46f5bd0739b53aed8ac677fa712943df7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.0.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8.35||~5.7"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "Mobile_Detect.php"
+ ],
+ "psr-0": {
+ "Detection": "namespaced/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Serban Ghita",
+ "email": "serbanghita@gmail.com",
+ "homepage": "http://mobiledetect.net",
+ "role": "Developer"
+ }
+ ],
+ "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.",
+ "homepage": "https://github.com/serbanghita/Mobile-Detect",
+ "keywords": [
+ "detect mobile devices",
+ "mobile",
+ "mobile detect",
+ "mobile detector",
+ "php mobile detect"
+ ],
+ "support": {
+ "issues": "https://github.com/serbanghita/Mobile-Detect/issues",
+ "source": "https://github.com/serbanghita/Mobile-Detect/tree/2.8.37"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/serbanghita",
+ "type": "github"
+ }
+ ],
+ "time": "2021-02-19T21:22:57+00:00"
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "v9.99.99",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
+ "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*",
+ "vimeo/psalm": "^1"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "polyfill",
+ "pseudorandom",
+ "random"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/random_compat/issues",
+ "source": "https://github.com/paragonie/random_compat"
+ },
+ "time": "2018-07-02T15:55:56+00:00"
+ },
+ {
+ "name": "paragonie/sodium_compat",
+ "version": "v1.14.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/sodium_compat.git",
+ "reference": "a1cfe0b21faf9c0b61ac0c6188c4af7fd6fd0db3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/a1cfe0b21faf9c0b61ac0c6188c4af7fd6fd0db3",
+ "reference": "a1cfe0b21faf9c0b61ac0c6188c4af7fd6fd0db3",
+ "shasum": ""
+ },
+ "require": {
+ "paragonie/random_compat": ">=1",
+ "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9"
+ },
+ "suggest": {
+ "ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.",
+ "ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security."
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "autoload.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "ISC"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com"
+ },
+ {
+ "name": "Frank Denis",
+ "email": "jedisct1@pureftpd.org"
+ }
+ ],
+ "description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists",
+ "keywords": [
+ "Authentication",
+ "BLAKE2b",
+ "ChaCha20",
+ "ChaCha20-Poly1305",
+ "Chapoly",
+ "Curve25519",
+ "Ed25519",
+ "EdDSA",
+ "Edwards-curve Digital Signature Algorithm",
+ "Elliptic Curve Diffie-Hellman",
+ "Poly1305",
+ "Pure-PHP cryptography",
+ "RFC 7748",
+ "RFC 8032",
+ "Salpoly",
+ "Salsa20",
+ "X25519",
+ "XChaCha20-Poly1305",
+ "XSalsa20-Poly1305",
+ "Xchacha20",
+ "Xsalsa20",
+ "aead",
+ "cryptography",
+ "ecdh",
+ "elliptic curve",
+ "elliptic curve cryptography",
+ "encryption",
+ "libsodium",
+ "php",
+ "public-key cryptography",
+ "secret-key cryptography",
+ "side-channel resistant"
+ ],
+ "support": {
+ "issues": "https://github.com/paragonie/sodium_compat/issues",
+ "source": "https://github.com/paragonie/sodium_compat/tree/v1.14.0"
+ },
+ "time": "2020-12-03T16:26:19+00:00"
+ },
+ {
+ "name": "psr/container",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf",
+ "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/1.1.1"
+ },
+ "time": "2021-03-05T17:36:06+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-message/tree/master"
+ },
+ "time": "2016-08-06T14:39:51+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
+ "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/1.1.3"
+ },
+ "time": "2020-03-23T09:12:05+00:00"
+ },
+ {
+ "name": "psr/simple-cache",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/simple-cache.git",
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\SimpleCache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interfaces for simple caching",
+ "keywords": [
+ "cache",
+ "caching",
+ "psr",
+ "psr-16",
+ "simple-cache"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/simple-cache/tree/master"
+ },
+ "time": "2017-10-23T01:57:42+00:00"
+ },
+ {
+ "name": "robmorgan/phinx",
+ "version": "0.11.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cakephp/phinx.git",
+ "reference": "3cdde73e0c33c410e076108b3e1603fabb5b330d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cakephp/phinx/zipball/3cdde73e0c33c410e076108b3e1603fabb5b330d",
+ "reference": "3cdde73e0c33c410e076108b3e1603fabb5b330d",
+ "shasum": ""
+ },
+ "require": {
+ "cakephp/collection": "^3.7",
+ "cakephp/database": "^3.7",
+ "php": ">=5.6",
+ "symfony/config": "^3.4|^4.0|^5.0",
+ "symfony/console": "^3.4|^4.0|^5.0",
+ "symfony/yaml": "^3.4|^4.0|^5.0"
+ },
+ "require-dev": {
+ "cakephp/cakephp-codesniffer": "^3.0",
+ "ext-json": "*",
+ "phpunit/phpunit": ">=5.7,<8.0",
+ "sebastian/comparator": ">=1.2.3"
+ },
+ "suggest": {
+ "ext-json": "Install if using JSON configuration format",
+ "symfony/yaml": "Install if using YAML configuration format"
+ },
+ "bin": [
+ "bin/phinx"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Phinx\\": "src/Phinx/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Rob Morgan",
+ "email": "robbym@gmail.com",
+ "homepage": "https://robmorgan.id.au",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Woody Gilk",
+ "email": "woody.gilk@gmail.com",
+ "homepage": "https://shadowhand.me",
+ "role": "Developer"
+ },
+ {
+ "name": "Richard Quadling",
+ "email": "rquadling@gmail.com",
+ "role": "Developer"
+ },
+ {
+ "name": "CakePHP Community",
+ "homepage": "https://github.com/cakephp/phinx/graphs/contributors",
+ "role": "Developer"
+ }
+ ],
+ "description": "Phinx makes it ridiculously easy to manage the database migrations for your PHP app.",
+ "homepage": "https://phinx.org",
+ "keywords": [
+ "database",
+ "database migrations",
+ "db",
+ "migrations",
+ "phinx"
+ ],
+ "support": {
+ "issues": "https://github.com/cakephp/phinx/issues",
+ "source": "https://github.com/cakephp/phinx/tree/0.11.7"
+ },
+ "time": "2020-05-09T13:59:05+00:00"
+ },
+ {
+ "name": "symfony/config",
+ "version": "v5.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/config.git",
+ "reference": "212d54675bf203ff8aef7d8cee8eecfb72f4a263"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/config/zipball/212d54675bf203ff8aef7d8cee8eecfb72f4a263",
+ "reference": "212d54675bf203ff8aef7d8cee8eecfb72f4a263",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1",
+ "symfony/filesystem": "^4.4|^5.0",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-php80": "^1.15"
+ },
+ "conflict": {
+ "symfony/finder": "<4.4"
+ },
+ "require-dev": {
+ "symfony/event-dispatcher": "^4.4|^5.0",
+ "symfony/finder": "^4.4|^5.0",
+ "symfony/messenger": "^4.4|^5.0",
+ "symfony/service-contracts": "^1.1|^2",
+ "symfony/yaml": "^4.4|^5.0"
+ },
+ "suggest": {
+ "symfony/yaml": "To use the yaml reference dumper"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Config\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/config/tree/v5.2.4"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-02-23T23:58:19+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v5.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "35f039df40a3b335ebf310f244cb242b3a83ac8d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/35f039df40a3b335ebf310f244cb242b3a83ac8d",
+ "reference": "35f039df40a3b335ebf310f244cb242b3a83ac8d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php73": "^1.8",
+ "symfony/polyfill-php80": "^1.15",
+ "symfony/service-contracts": "^1.1|^2",
+ "symfony/string": "^5.1"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<4.4",
+ "symfony/dotenv": "<5.1",
+ "symfony/event-dispatcher": "<4.4",
+ "symfony/lock": "<4.4",
+ "symfony/process": "<4.4"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "^4.4|^5.0",
+ "symfony/dependency-injection": "^4.4|^5.0",
+ "symfony/event-dispatcher": "^4.4|^5.0",
+ "symfony/lock": "^4.4|^5.0",
+ "symfony/process": "^4.4|^5.0",
+ "symfony/var-dumper": "^4.4|^5.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/lock": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Eases the creation of beautiful and testable command line interfaces",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "cli",
+ "command line",
+ "console",
+ "terminal"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/console/tree/v5.2.6"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-28T09:42:18+00:00"
+ },
+ {
+ "name": "symfony/deprecation-contracts",
+ "version": "v2.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665",
+ "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.2-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "files": [
+ "function.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/deprecation-contracts/tree/master"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-09-07T11:33:47+00:00"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "v5.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "8c86a82f51658188119e62cff0a050a12d09836f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/8c86a82f51658188119e62cff0a050a12d09836f",
+ "reference": "8c86a82f51658188119e62cff0a050a12d09836f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "~1.8"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Filesystem\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides basic utilities for the filesystem",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/filesystem/tree/v5.2.6"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-28T14:30:26+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
+ "reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-07T16:49:33+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-grapheme",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+ "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5601e09b69f26c1828b13b6bb87cb07cddba3170",
+ "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's grapheme_* functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "grapheme",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-22T09:19:47+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248",
+ "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-22T09:19:47+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "5232de97ee3b75b0360528dae24e73db49566ab1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1",
+ "reference": "5232de97ee3b75b0360528dae24e73db49566ab1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-22T09:19:47+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php73",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php73.git",
+ "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
+ "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php73\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-07T16:49:33+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php80",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91",
+ "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php80\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-07T16:49:33+00:00"
+ },
+ {
+ "name": "symfony/service-contracts",
+ "version": "v2.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1",
+ "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "psr/container": "^1.0"
+ },
+ "suggest": {
+ "symfony/service-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.2-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Service\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to writing services",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/service-contracts/tree/master"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-09-07T11:33:47+00:00"
+ },
+ {
+ "name": "symfony/string",
+ "version": "v5.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/string.git",
+ "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/string/zipball/ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572",
+ "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-intl-grapheme": "~1.0",
+ "symfony/polyfill-intl-normalizer": "~1.0",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php80": "~1.15"
+ },
+ "require-dev": {
+ "symfony/error-handler": "^4.4|^5.0",
+ "symfony/http-client": "^4.4|^5.0",
+ "symfony/translation-contracts": "^1.1|^2",
+ "symfony/var-exporter": "^4.4|^5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\String\\": ""
+ },
+ "files": [
+ "Resources/functions.php"
+ ],
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "grapheme",
+ "i18n",
+ "string",
+ "unicode",
+ "utf-8",
+ "utf8"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v5.2.6"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-17T17:12:15+00:00"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v5.2.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "298a08ddda623485208506fcee08817807a251dd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/298a08ddda623485208506fcee08817807a251dd",
+ "reference": "298a08ddda623485208506fcee08817807a251dd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1",
+ "symfony/polyfill-ctype": "~1.8"
+ },
+ "conflict": {
+ "symfony/console": "<4.4"
+ },
+ "require-dev": {
+ "symfony/console": "^4.4|^5.0"
+ },
+ "suggest": {
+ "symfony/console": "For validating YAML files using the lint command"
+ },
+ "bin": [
+ "Resources/bin/yaml-lint"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Loads and dumps YAML files",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/yaml/tree/v5.2.5"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-06T07:59:01+00:00"
+ },
+ {
+ "name": "tuupola/base58",
+ "version": "2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/tuupola/base58.git",
+ "reference": "4cd1a3972679946e87c0746f59ff8f0760240b4c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/tuupola/base58/zipball/4cd1a3972679946e87c0746f59ff8f0760240b4c",
+ "reference": "4cd1a3972679946e87c0746f59ff8f0760240b4c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1|^8.0"
+ },
+ "require-dev": {
+ "overtrue/phplint": "^1.0.0",
+ "phpbench/phpbench": "^0.13.0",
+ "phpstan/phpstan": "^0.12.37",
+ "phpunit/phpunit": "^7.0|^8.0|^9.0",
+ "squizlabs/php_codesniffer": "^3.0"
+ },
+ "suggest": {
+ "ext-gmp": "GMP extension provides the fastest encoding and decoding."
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Tuupola\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mika Tuupola",
+ "email": "tuupola@appelsiini.net",
+ "homepage": "https://appelsiini.net/",
+ "role": "Developer"
+ }
+ ],
+ "description": "Base58 encoder and decoder for arbitrary data",
+ "homepage": "https://github.com/tuupola/base58",
+ "keywords": [
+ "base58"
+ ],
+ "support": {
+ "issues": "https://github.com/tuupola/base58/issues",
+ "source": "https://github.com/tuupola/base58/tree/2.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/tuupola",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-09T11:38:20+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "ajgl/breakpoint-twig-extension",
+ "version": "0.3.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ajgarlag/AjglBreakpointTwigExtension.git",
+ "reference": "9875feea0ac4bc3c9f308c62bae4727669d6052a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ajgarlag/AjglBreakpointTwigExtension/zipball/9875feea0ac4bc3c9f308c62bae4727669d6052a",
+ "reference": "9875feea0ac4bc3c9f308c62bae4727669d6052a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6",
+ "twig/twig": "^1.34|^2.0|^3.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.18",
+ "symfony/framework-bundle": "^2.7|^3.4|^4.4|^5.2",
+ "symfony/phpunit-bridge": "^4.4|^5.2",
+ "symfony/twig-bundle": "^2.7|^3.4|^4.4|^5.2"
+ },
+ "suggest": {
+ "ext-xdebug": "The Xdebug extension is required for the breakpoint to work",
+ "symfony/framework-bundle": "The framework bundle to integrate the extension into Symfony",
+ "symfony/twig-bundle": "The twig bundle to integrate the extension into Symfony"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Ajgl\\Twig\\Extension\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Antonio J. GarcÃa Lagar",
+ "email": "aj@garcialagar.es",
+ "homepage": "http://aj.garcialagar.es",
+ "role": "developer"
+ }
+ ],
+ "description": "Twig extension to set breakpoints",
+ "homepage": "https://github.com/ajgarlag/AjglBreakpointTwigExtension",
+ "keywords": [
+ "Xdebug",
+ "breakpoint",
+ "twig"
+ ],
+ "support": {
+ "issues": "https://github.com/ajgarlag/AjglBreakpointTwigExtension/issues",
+ "source": "https://github.com/ajgarlag/AjglBreakpointTwigExtension/tree/0.3.5"
+ },
+ "time": "2021-02-08T10:48:05+00:00"
+ },
+ {
+ "name": "aptoma/twig-markdown",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/aptoma/twig-markdown.git",
+ "reference": "64a9c5c7418c08faf91c4410b34bdb65fb25c23d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/aptoma/twig-markdown/zipball/64a9c5c7418c08faf91c4410b34bdb65fb25c23d",
+ "reference": "64a9c5c7418c08faf91c4410b34bdb65fb25c23d",
+ "shasum": ""
+ },
+ "require": {
+ "twig/twig": "~1.12"
+ },
+ "require-dev": {
+ "codeclimate/php-test-reporter": "dev-master",
+ "erusev/parsedown": "^1.6",
+ "knplabs/github-api": "~1.2",
+ "league/commonmark": "~0.5",
+ "michelf/php-markdown": "~1",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "~0.6"
+ },
+ "suggest": {
+ "knplabs/github-api": "Needed for using GitHub's Markdown engine provided through their API.",
+ "michelf/php-markdown": "Original Markdown engine with MarkdownExtra."
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Aptoma": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Joris Berthelot",
+ "email": "joris@berthelot.tel"
+ },
+ {
+ "name": "Gunnar Lium",
+ "email": "gunnar@aptoma.com"
+ }
+ ],
+ "description": "Twig extension to work with Markdown content",
+ "keywords": [
+ "markdown",
+ "twig"
+ ],
+ "support": {
+ "issues": "https://github.com/aptoma/twig-markdown/issues",
+ "source": "https://github.com/aptoma/twig-markdown/tree/master"
+ },
+ "time": "2015-10-23T20:27:08+00:00"
+ },
+ {
+ "name": "asm89/twig-cache-extension",
+ "version": "1.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/asm89/twig-cache-extension.git",
+ "reference": "13787226956ec766f4770722082288097aebaaf3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/asm89/twig-cache-extension/zipball/13787226956ec766f4770722082288097aebaaf3",
+ "reference": "13787226956ec766f4770722082288097aebaaf3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.2",
+ "twig/twig": "^1.0|^2.0"
+ },
+ "require-dev": {
+ "doctrine/cache": "~1.0",
+ "phpunit/phpunit": "^5.0 || ^4.8.10"
+ },
+ "suggest": {
+ "psr/cache-implementation": "To make use of PSR-6 cache implementation via PsrCacheAdapter."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Alexander",
+ "email": "iam.asm89@gmail.com"
+ }
+ ],
+ "description": "Cache fragments of templates directly within Twig.",
+ "homepage": "https://github.com/asm89/twig-cache-extension",
+ "keywords": [
+ "cache",
+ "extension",
+ "twig"
+ ],
+ "support": {
+ "issues": "https://github.com/asm89/twig-cache-extension/issues",
+ "source": "https://github.com/asm89/twig-cache-extension/tree/1.4.0"
+ },
+ "abandoned": "twig/cache-extension",
+ "time": "2020-01-01T20:47:37+00:00"
+ },
+ {
+ "name": "cakephp/bake",
+ "version": "1.12.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cakephp/bake.git",
+ "reference": "33e8ee8419ba36c13fa4074c208c93352b5530cf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cakephp/bake/zipball/33e8ee8419ba36c13fa4074c208c93352b5530cf",
+ "reference": "33e8ee8419ba36c13fa4074c208c93352b5530cf",
+ "shasum": ""
+ },
+ "require": {
+ "cakephp/cakephp": "^3.8.0",
+ "cakephp/plugin-installer": "^1.0",
+ "php": ">=5.6.0",
+ "wyrihaximus/twig-view": "^4.3.7"
+ },
+ "require-dev": {
+ "cakephp/cakephp-codesniffer": "^3.0",
+ "phpunit/phpunit": "^5.7.14|^6.0"
+ },
+ "type": "cakephp-plugin",
+ "autoload": {
+ "psr-4": {
+ "Bake\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "CakePHP Community",
+ "homepage": "https://github.com/cakephp/bake/graphs/contributors"
+ }
+ ],
+ "description": "Bake plugin for CakePHP 3",
+ "homepage": "https://github.com/cakephp/bake",
+ "keywords": [
+ "bake",
+ "cakephp"
+ ],
+ "support": {
+ "forum": "https://stackoverflow.com/tags/cakephp",
+ "irc": "irc://irc.freenode.org/cakephp",
+ "issues": "https://github.com/cakephp/bake/issues",
+ "source": "https://github.com/cakephp/bake"
+ },
+ "time": "2019-12-07T20:34:43+00:00"
+ },
+ {
+ "name": "cakephp/cakephp-codesniffer",
+ "version": "3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cakephp/cakephp-codesniffer.git",
+ "reference": "7998a191e787fd5b68cb635d7050cb0d7b55e1a1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cakephp/cakephp-codesniffer/zipball/7998a191e787fd5b68cb635d7050cb0d7b55e1a1",
+ "reference": "7998a191e787fd5b68cb635d7050cb0d7b55e1a1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6",
+ "squizlabs/php_codesniffer": "^3.0.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "<6.0"
+ },
+ "type": "phpcodesniffer-standard",
+ "autoload": {
+ "psr-4": {
+ "CakePHP\\": "CakePHP/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "CakePHP Community",
+ "homepage": "https://github.com/cakephp/cakephp-codesniffer/graphs/contributors"
+ }
+ ],
+ "description": "CakePHP CodeSniffer Standards",
+ "homepage": "https://cakephp.org",
+ "keywords": [
+ "codesniffer",
+ "framework"
+ ],
+ "support": {
+ "forum": "https://stackoverflow.com/tags/cakephp",
+ "irc": "irc://irc.freenode.org/cakephp",
+ "issues": "https://github.com/cakephp/cakephp-codesniffer/issues",
+ "source": "https://github.com/cakephp/cakephp-codesniffer"
+ },
+ "time": "2019-12-07T03:02:34+00:00"
+ },
+ {
+ "name": "cakephp/debug_kit",
+ "version": "3.22.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cakephp/debug_kit.git",
+ "reference": "5bec3c49a2b8d9bd12655f2ec35e52ec90befe17"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cakephp/debug_kit/zipball/5bec3c49a2b8d9bd12655f2ec35e52ec90befe17",
+ "reference": "5bec3c49a2b8d9bd12655f2ec35e52ec90befe17",
+ "shasum": ""
+ },
+ "require": {
+ "cakephp/cakephp": "^3.7.0",
+ "cakephp/chronos": "^1.0.0",
+ "cakephp/plugin-installer": "^1.0.0",
+ "composer/composer": "^1.3.0",
+ "jdorn/sql-formatter": "^1.2.0",
+ "php": ">=5.6.0"
+ },
+ "require-dev": {
+ "cakephp/authorization": "^1.3.2",
+ "cakephp/cakephp-codesniffer": "^3.0",
+ "phpunit/phpunit": "^5.7.14|^6.0"
+ },
+ "suggest": {
+ "ext-pdo_sqlite": "DebugKit needs to store panel data in a database. SQLite is simple and easy to use."
+ },
+ "type": "cakephp-plugin",
+ "autoload": {
+ "psr-4": {
+ "DebugKit\\": "src/",
+ "DebugKit\\Test\\Fixture\\": "tests/Fixture/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mark Story",
+ "homepage": "https://mark-story.com",
+ "role": "Author"
+ },
+ {
+ "name": "CakePHP Community",
+ "homepage": "https://github.com/cakephp/debug_kit/graphs/contributors"
+ }
+ ],
+ "description": "CakePHP Debug Kit",
+ "homepage": "https://github.com/cakephp/debug_kit",
+ "keywords": [
+ "cakephp",
+ "debug",
+ "kit"
+ ],
+ "support": {
+ "forum": "http://stackoverflow.com/tags/cakephp",
+ "irc": "irc://irc.freenode.org/cakephp",
+ "issues": "https://github.com/cakephp/debug_kit/issues",
+ "source": "https://github.com/cakephp/debug_kit"
+ },
+ "time": "2020-04-22T17:27:39+00:00"
+ },
+ {
+ "name": "composer/ca-bundle",
+ "version": "1.2.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/ca-bundle.git",
+ "reference": "78a0e288fdcebf92aa2318a8d3656168da6ac1a5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/ca-bundle/zipball/78a0e288fdcebf92aa2318a8d3656168da6ac1a5",
+ "reference": "78a0e288fdcebf92aa2318a8d3656168da6ac1a5",
+ "shasum": ""
+ },
+ "require": {
+ "ext-openssl": "*",
+ "ext-pcre": "*",
+ "php": "^5.3.2 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^0.12.55",
+ "psr/log": "^1.0",
+ "symfony/phpunit-bridge": "^4.2 || ^5",
+ "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\CaBundle\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
+ "keywords": [
+ "cabundle",
+ "cacert",
+ "certificate",
+ "ssl",
+ "tls"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/ca-bundle/issues",
+ "source": "https://github.com/composer/ca-bundle/tree/1.2.9"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-12T12:10:35+00:00"
+ },
+ {
+ "name": "composer/composer",
+ "version": "1.10.21",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/composer.git",
+ "reference": "04021432f4a9cbd9351dd166b8c193f42c36a39c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/composer/zipball/04021432f4a9cbd9351dd166b8c193f42c36a39c",
+ "reference": "04021432f4a9cbd9351dd166b8c193f42c36a39c",
+ "shasum": ""
+ },
+ "require": {
+ "composer/ca-bundle": "^1.0",
+ "composer/semver": "^1.0",
+ "composer/spdx-licenses": "^1.2",
+ "composer/xdebug-handler": "^1.1",
+ "justinrainbow/json-schema": "^5.2.10",
+ "php": "^5.3.2 || ^7.0 || ^8.0",
+ "psr/log": "^1.0",
+ "seld/jsonlint": "^1.4",
+ "seld/phar-utils": "^1.0",
+ "symfony/console": "^2.7 || ^3.0 || ^4.0 || ^5.0",
+ "symfony/filesystem": "^2.7 || ^3.0 || ^4.0 || ^5.0",
+ "symfony/finder": "^2.7 || ^3.0 || ^4.0 || ^5.0",
+ "symfony/process": "^2.7 || ^3.0 || ^4.0 || ^5.0"
+ },
+ "conflict": {
+ "symfony/console": "2.8.38"
+ },
+ "require-dev": {
+ "phpspec/prophecy": "^1.10",
+ "symfony/phpunit-bridge": "^4.2"
+ },
+ "suggest": {
+ "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages",
+ "ext-zip": "Enabling the zip extension allows you to unzip archives",
+ "ext-zlib": "Allow gzip compression of HTTP requests"
+ },
+ "bin": [
+ "bin/composer"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.10-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\": "src/Composer"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.",
+ "homepage": "https://getcomposer.org/",
+ "keywords": [
+ "autoload",
+ "dependency",
+ "package"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/composer/issues",
+ "source": "https://github.com/composer/composer/tree/1.10.21"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-04-01T07:16:35+00:00"
+ },
+ {
+ "name": "composer/semver",
+ "version": "1.7.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/semver.git",
+ "reference": "647490bbcaf7fc4891c58f47b825eb99d19c377a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/semver/zipball/647490bbcaf7fc4891c58f47b825eb99d19c377a",
+ "reference": "647490bbcaf7fc4891c58f47b825eb99d19c377a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.5 || ^5.0.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Semver\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ },
+ {
+ "name": "Rob Bast",
+ "email": "rob.bast@gmail.com",
+ "homepage": "http://robbast.nl"
+ }
+ ],
+ "description": "Semver library that offers utilities, version constraint parsing and validation.",
+ "keywords": [
+ "semantic",
+ "semver",
+ "validation",
+ "versioning"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/semver/issues",
+ "source": "https://github.com/composer/semver/tree/1.7.2"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-12-03T15:47:16+00:00"
+ },
+ {
+ "name": "composer/spdx-licenses",
+ "version": "1.5.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/spdx-licenses.git",
+ "reference": "de30328a7af8680efdc03e396aad24befd513200"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/de30328a7af8680efdc03e396aad24befd513200",
+ "reference": "de30328a7af8680efdc03e396aad24befd513200",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Spdx\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ },
+ {
+ "name": "Rob Bast",
+ "email": "rob.bast@gmail.com",
+ "homepage": "http://robbast.nl"
+ }
+ ],
+ "description": "SPDX licenses list and validation library.",
+ "keywords": [
+ "license",
+ "spdx",
+ "validator"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/spdx-licenses/issues",
+ "source": "https://github.com/composer/spdx-licenses/tree/1.5.5"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-12-03T16:04:16+00:00"
+ },
+ {
+ "name": "composer/xdebug-handler",
+ "version": "1.4.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/xdebug-handler.git",
+ "reference": "f27e06cd9675801df441b3656569b328e04aa37c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f27e06cd9675801df441b3656569b328e04aa37c",
+ "reference": "f27e06cd9675801df441b3656569b328e04aa37c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0 || ^8.0",
+ "psr/log": "^1.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^0.12.55",
+ "symfony/phpunit-bridge": "^4.2 || ^5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Composer\\XdebugHandler\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "John Stevenson",
+ "email": "john-stevenson@blueyonder.co.uk"
+ }
+ ],
+ "description": "Restarts a process without Xdebug.",
+ "keywords": [
+ "Xdebug",
+ "performance"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/xdebug-handler/issues",
+ "source": "https://github.com/composer/xdebug-handler/tree/1.4.6"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-25T17:01:18+00:00"
+ },
+ {
+ "name": "dnoegel/php-xdg-base-dir",
+ "version": "v0.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/dnoegel/php-xdg-base-dir.git",
+ "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
+ "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "XdgBaseDir\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "implementation of xdg base directory specification for php",
+ "support": {
+ "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues",
+ "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1"
+ },
+ "time": "2019-12-04T15:06:13+00:00"
+ },
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
+ "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^8.0",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
+ "phpstan/phpstan": "^0.12",
+ "phpstan/phpstan-phpunit": "^0.12",
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "https://ocramius.github.io/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/instantiator/issues",
+ "source": "https://github.com/doctrine/instantiator/tree/1.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-11-10T18:47:58+00:00"
+ },
+ {
+ "name": "jasny/twig-extensions",
+ "version": "v1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/jasny/twig-extensions.git",
+ "reference": "30bdf3a3903c021544f36332c9d5d4d563527da4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/jasny/twig-extensions/zipball/30bdf3a3903c021544f36332c9d5d4d563527da4",
+ "reference": "30bdf3a3903c021544f36332c9d5d4d563527da4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0.0 | >=5.6.0",
+ "twig/twig": "^2.0 | ^1.12"
+ },
+ "require-dev": {
+ "ext-intl": "*",
+ "ext-pcre": "*",
+ "jasny/php-code-quality": "^2.1",
+ "phpunit/phpunit": "^5.0"
+ },
+ "suggest": {
+ "ext-intl": "Required for the use of the LocalDate Twig extension",
+ "ext-pcre": "Required for the use of the PCRE Twig extension"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Jasny\\Twig\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Arnold Daniels",
+ "email": "arnold@jasny.net",
+ "homepage": "http://www.jasny.net"
+ }
+ ],
+ "description": "A set of useful Twig filters",
+ "homepage": "http://github.com/jasny/twig-extensions#README",
+ "keywords": [
+ "PCRE",
+ "array",
+ "date",
+ "datetime",
+ "preg",
+ "regex",
+ "templating",
+ "text",
+ "time"
+ ],
+ "support": {
+ "issues": "https://github.com/jasny/twig-extensions/issues",
+ "source": "https://github.com/jasny/twig-extensions"
+ },
+ "time": "2017-09-13T07:38:01+00:00"
+ },
+ {
+ "name": "jdorn/sql-formatter",
+ "version": "v1.2.17",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/jdorn/sql-formatter.git",
+ "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/jdorn/sql-formatter/zipball/64990d96e0959dff8e059dfcdc1af130728d92bc",
+ "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.4"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "3.7.*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "lib"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jeremy Dorn",
+ "email": "jeremy@jeremydorn.com",
+ "homepage": "http://jeremydorn.com/"
+ }
+ ],
+ "description": "a PHP SQL highlighting library",
+ "homepage": "https://github.com/jdorn/sql-formatter/",
+ "keywords": [
+ "highlight",
+ "sql"
+ ],
+ "support": {
+ "issues": "https://github.com/jdorn/sql-formatter/issues",
+ "source": "https://github.com/jdorn/sql-formatter/tree/master"
+ },
+ "time": "2014-01-12T16:20:24+00:00"
+ },
+ {
+ "name": "josegonzalez/dotenv",
+ "version": "3.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/josegonzalez/php-dotenv.git",
+ "reference": "f19174d9d7213a6c20e8e5e268aa7dd042d821ca"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/josegonzalez/php-dotenv/zipball/f19174d9d7213a6c20e8e5e268aa7dd042d821ca",
+ "reference": "f19174d9d7213a6c20e8e5e268aa7dd042d821ca",
+ "shasum": ""
+ },
+ "require": {
+ "m1/env": "2.*",
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "php-mock/php-mock-phpunit": "^1.1",
+ "satooshi/php-coveralls": "1.*",
+ "squizlabs/php_codesniffer": "2.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "josegonzalez\\Dotenv": [
+ "src",
+ "tests"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jose Diaz-Gonzalez",
+ "email": "dotenv@josegonzalez.com",
+ "homepage": "http://josediazgonzalez.com",
+ "role": "Maintainer"
+ }
+ ],
+ "description": "dotenv file parsing for PHP",
+ "homepage": "https://github.com/josegonzalez/php-dotenv",
+ "keywords": [
+ "configuration",
+ "dotenv",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/josegonzalez/php-dotenv/issues",
+ "source": "https://github.com/josegonzalez/php-dotenv/tree/master"
+ },
+ "time": "2017-09-19T15:49:58+00:00"
+ },
+ {
+ "name": "justinrainbow/json-schema",
+ "version": "5.2.10",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/justinrainbow/json-schema.git",
+ "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b",
+ "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
+ "json-schema/json-schema-test-suite": "1.2.0",
+ "phpunit/phpunit": "^4.8.35"
+ },
+ "bin": [
+ "bin/validate-json"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "JsonSchema\\": "src/JsonSchema/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bruno Prieto Reis",
+ "email": "bruno.p.reis@gmail.com"
+ },
+ {
+ "name": "Justin Rainbow",
+ "email": "justin.rainbow@gmail.com"
+ },
+ {
+ "name": "Igor Wiedler",
+ "email": "igor@wiedler.ch"
+ },
+ {
+ "name": "Robert Schönthal",
+ "email": "seroscho@googlemail.com"
+ }
+ ],
+ "description": "A library to validate a json schema.",
+ "homepage": "https://github.com/justinrainbow/json-schema",
+ "keywords": [
+ "json",
+ "schema"
+ ],
+ "support": {
+ "issues": "https://github.com/justinrainbow/json-schema/issues",
+ "source": "https://github.com/justinrainbow/json-schema/tree/5.2.10"
+ },
+ "time": "2020-05-27T16:41:55+00:00"
+ },
+ {
+ "name": "m1/env",
+ "version": "2.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/m1/Env.git",
+ "reference": "5c296e3e13450a207e12b343f3af1d7ab569f6f3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/m1/Env/zipball/5c296e3e13450a207e12b343f3af1d7ab569f6f3",
+ "reference": "5c296e3e13450a207e12b343f3af1d7ab569f6f3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*",
+ "scrutinizer/ocular": "~1.1",
+ "squizlabs/php_codesniffer": "^2.3"
+ },
+ "suggest": {
+ "josegonzalez/dotenv": "For loading of .env",
+ "m1/vars": "For loading of configs"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "M1\\Env\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Miles Croxford",
+ "email": "hello@milescroxford.com",
+ "homepage": "http://milescroxford.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "Env is a lightweight library bringing .env file parser compatibility to PHP. In short - it enables you to read .env files with PHP.",
+ "homepage": "https://github.com/m1/Env",
+ "keywords": [
+ ".env",
+ "config",
+ "dotenv",
+ "env",
+ "loader",
+ "m1",
+ "parser",
+ "support"
+ ],
+ "support": {
+ "issues": "https://github.com/m1/Env/issues",
+ "source": "https://github.com/m1/Env/tree/2.2.0"
+ },
+ "time": "2020-02-19T09:02:13+00:00"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.10.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
+ "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "replace": {
+ "myclabs/deep-copy": "self.version"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.0",
+ "doctrine/common": "^2.6",
+ "phpunit/phpunit": "^7.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ },
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "support": {
+ "issues": "https://github.com/myclabs/DeepCopy/issues",
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2"
+ },
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-11-13T09:40:50+00:00"
+ },
+ {
+ "name": "nikic/php-parser",
+ "version": "v4.10.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e",
+ "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "ircmaxell/php-yacc": "^0.0.7",
+ "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "bin": [
+ "bin/php-parse"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpParser\\": "lib/PhpParser"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Nikita Popov"
+ }
+ ],
+ "description": "A PHP parser written in PHP",
+ "keywords": [
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/nikic/PHP-Parser/issues",
+ "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4"
+ },
+ "time": "2020-12-20T10:01:03+00:00"
+ },
+ {
+ "name": "phar-io/manifest",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/manifest.git",
+ "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0",
+ "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-phar": "*",
+ "phar-io/version": "^1.0.1",
+ "php": "^5.6 || ^7.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+ "support": {
+ "issues": "https://github.com/phar-io/manifest/issues",
+ "source": "https://github.com/phar-io/manifest/tree/master"
+ },
+ "time": "2017-03-05T18:14:27+00:00"
+ },
+ {
+ "name": "phar-io/version",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/version.git",
+ "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df",
+ "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Library for handling version information and constraints",
+ "support": {
+ "issues": "https://github.com/phar-io/version/issues",
+ "source": "https://github.com/phar-io/version/tree/master"
+ },
+ "time": "2017-03-05T17:38:23+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "2.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-2.x": "2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
+ "keywords": [
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
+ },
+ "time": "2020-06-27T09:03:43+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "5.2.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556",
+ "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556",
+ "shasum": ""
+ },
+ "require": {
+ "ext-filter": "*",
+ "php": "^7.2 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.2",
+ "phpdocumentor/type-resolver": "^1.3",
+ "webmozart/assert": "^1.9.1"
+ },
+ "require-dev": {
+ "mockery/mockery": "~1.3.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ },
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "account@ijaap.nl"
+ }
+ ],
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master"
+ },
+ "time": "2020-09-03T19:13:55+00:00"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "1.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
+ "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.0"
+ },
+ "require-dev": {
+ "ext-tokenizer": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-1.x": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+ "support": {
+ "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0"
+ },
+ "time": "2020-09-17T18:55:26+00:00"
+ },
+ {
+ "name": "phpspec/prophecy",
+ "version": "v1.10.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "451c3cd1418cf640de218914901e51b064abb093"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093",
+ "reference": "451c3cd1418cf640de218914901e51b064abb093",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
+ "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^2.5 || ^3.2",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.10.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Prophecy\\": "src/Prophecy"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ },
+ {
+ "name": "Marcello Duarte",
+ "email": "marcello.duarte@gmail.com"
+ }
+ ],
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
+ "homepage": "https://github.com/phpspec/prophecy",
+ "keywords": [
+ "Double",
+ "Dummy",
+ "fake",
+ "mock",
+ "spy",
+ "stub"
+ ],
+ "support": {
+ "issues": "https://github.com/phpspec/prophecy/issues",
+ "source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
+ },
+ "time": "2020-03-05T15:02:03+00:00"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "5.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "c89677919c5dd6d3b3852f230a663118762218ac"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac",
+ "reference": "c89677919c5dd6d3b3852f230a663118762218ac",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.0",
+ "phpunit/php-file-iterator": "^1.4.2",
+ "phpunit/php-text-template": "^1.2.1",
+ "phpunit/php-token-stream": "^2.0.1",
+ "sebastian/code-unit-reverse-lookup": "^1.0.1",
+ "sebastian/environment": "^3.0",
+ "sebastian/version": "^2.0.1",
+ "theseer/tokenizer": "^1.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "suggest": {
+ "ext-xdebug": "^2.5.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.3.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/5.3"
+ },
+ "time": "2018-04-06T15:36:58+00:00"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "1.4.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
+ "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.net/phpunit",
+ "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5"
+ },
+ "time": "2017-11-27T13:52:08+00:00"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
+ },
+ "time": "2015-06-21T13:50:34+00:00"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "1.0.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-timer/issues",
+ "source": "https://github.com/sebastianbergmann/php-timer/tree/master"
+ },
+ "time": "2017-02-26T11:10:40+00:00"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "2.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "791198a2c6254db10131eecfe8c06670700904db"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db",
+ "reference": "791198a2c6254db10131eecfe8c06670700904db",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.2.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
+ "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master"
+ },
+ "abandoned": true,
+ "time": "2017-11-27T05:48:46+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "6.5.14",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7",
+ "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "myclabs/deep-copy": "^1.6.1",
+ "phar-io/manifest": "^1.0.1",
+ "phar-io/version": "^1.0",
+ "php": "^7.0",
+ "phpspec/prophecy": "^1.7",
+ "phpunit/php-code-coverage": "^5.3",
+ "phpunit/php-file-iterator": "^1.4.3",
+ "phpunit/php-text-template": "^1.2.1",
+ "phpunit/php-timer": "^1.0.9",
+ "phpunit/phpunit-mock-objects": "^5.0.9",
+ "sebastian/comparator": "^2.1",
+ "sebastian/diff": "^2.0",
+ "sebastian/environment": "^3.1",
+ "sebastian/exporter": "^3.1",
+ "sebastian/global-state": "^2.0",
+ "sebastian/object-enumerator": "^3.0.3",
+ "sebastian/resource-operations": "^1.0",
+ "sebastian/version": "^2.0.1"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "3.0.2",
+ "phpunit/dbunit": "<3.0"
+ },
+ "require-dev": {
+ "ext-pdo": "*"
+ },
+ "suggest": {
+ "ext-xdebug": "*",
+ "phpunit/php-invoker": "^1.1"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.5.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/6.5.14"
+ },
+ "time": "2019-02-01T05:22:47+00:00"
+ },
+ {
+ "name": "phpunit/phpunit-mock-objects",
+ "version": "5.0.10",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
+ "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f",
+ "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.5",
+ "php": "^7.0",
+ "phpunit/php-text-template": "^1.2.1",
+ "sebastian/exporter": "^3.1"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<6.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.5.11"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Mock Object library for PHPUnit",
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "keywords": [
+ "mock",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues",
+ "source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/5.0.10"
+ },
+ "abandoned": true,
+ "time": "2018-08-09T05:50:03+00:00"
+ },
+ {
+ "name": "psy/psysh",
+ "version": "v0.10.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/bobthecow/psysh.git",
+ "reference": "a395af46999a12006213c0c8346c9445eb31640c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/bobthecow/psysh/zipball/a395af46999a12006213c0c8346c9445eb31640c",
+ "reference": "a395af46999a12006213c0c8346c9445eb31640c",
+ "shasum": ""
+ },
+ "require": {
+ "dnoegel/php-xdg-base-dir": "0.1.*",
+ "ext-json": "*",
+ "ext-tokenizer": "*",
+ "nikic/php-parser": "~4.0|~3.0|~2.0|~1.3",
+ "php": "^8.0 || ^7.0 || ^5.5.9",
+ "symfony/console": "~5.0|~4.0|~3.0|^2.4.2|~2.3.10",
+ "symfony/var-dumper": "~5.0|~4.0|~3.0|~2.7"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.2",
+ "hoa/console": "3.17.*"
+ },
+ "suggest": {
+ "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)",
+ "ext-pdo-sqlite": "The doc command requires SQLite to work.",
+ "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.",
+ "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.",
+ "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit."
+ },
+ "bin": [
+ "bin/psysh"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.10.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions.php"
+ ],
+ "psr-4": {
+ "Psy\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Justin Hileman",
+ "email": "justin@justinhileman.info",
+ "homepage": "http://justinhileman.com"
+ }
+ ],
+ "description": "An interactive shell for modern PHP.",
+ "homepage": "http://psysh.org",
+ "keywords": [
+ "REPL",
+ "console",
+ "interactive",
+ "shell"
+ ],
+ "support": {
+ "issues": "https://github.com/bobthecow/psysh/issues",
+ "source": "https://github.com/bobthecow/psysh/tree/v0.10.7"
+ },
+ "time": "2021-03-14T02:14:56+00:00"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
+ "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T08:15:22+00:00"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "2.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9",
+ "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "sebastian/diff": "^2.0 || ^3.0",
+ "sebastian/exporter": "^3.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "https://github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/comparator/issues",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/master"
+ },
+ "time": "2018-02-01T13:46:46+00:00"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd",
+ "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/diff/issues",
+ "source": "https://github.com/sebastianbergmann/diff/tree/master"
+ },
+ "time": "2017-08-03T08:09:46+00:00"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5",
+ "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/environment/issues",
+ "source": "https://github.com/sebastianbergmann/environment/tree/master"
+ },
+ "time": "2017-07-01T08:51:00+00:00"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "3.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e",
+ "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0",
+ "sebastian/recursion-context": "^3.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/exporter/issues",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:47:53+00:00"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+ "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/global-state/issues",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0"
+ },
+ "time": "2017-04-27T15:39:26+00:00"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "3.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
+ "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0",
+ "sebastian/object-reflector": "^1.1.1",
+ "sebastian/recursion-context": "^3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
+ "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:40:27+00:00"
+ },
+ {
+ "name": "sebastian/object-reflector",
+ "version": "1.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
+ "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Allows reflection of object attributes, including inherited and non-public ones",
+ "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:37:18+00:00"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "3.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
+ "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:34:24+00:00"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
+ "source": "https://github.com/sebastianbergmann/resource-operations/tree/master"
+ },
+ "time": "2015-07-28T20:34:47+00:00"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/version/issues",
+ "source": "https://github.com/sebastianbergmann/version/tree/master"
+ },
+ "time": "2016-10-03T07:35:21+00:00"
+ },
+ {
+ "name": "seld/jsonlint",
+ "version": "1.8.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Seldaek/jsonlint.git",
+ "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9ad6ce79c342fbd44df10ea95511a1b24dee5b57",
+ "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ },
+ "bin": [
+ "bin/jsonlint"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Seld\\JsonLint\\": "src/Seld/JsonLint/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "JSON Linter",
+ "keywords": [
+ "json",
+ "linter",
+ "parser",
+ "validator"
+ ],
+ "support": {
+ "issues": "https://github.com/Seldaek/jsonlint/issues",
+ "source": "https://github.com/Seldaek/jsonlint/tree/1.8.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/Seldaek",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-11-11T09:19:24+00:00"
+ },
+ {
+ "name": "seld/phar-utils",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Seldaek/phar-utils.git",
+ "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8674b1d84ffb47cc59a101f5d5a3b61e87d23796",
+ "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Seld\\PharUtils\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be"
+ }
+ ],
+ "description": "PHAR file format utilities, for when PHP phars you up",
+ "keywords": [
+ "phar"
+ ],
+ "support": {
+ "issues": "https://github.com/Seldaek/phar-utils/issues",
+ "source": "https://github.com/Seldaek/phar-utils/tree/master"
+ },
+ "time": "2020-07-07T18:42:57+00:00"
+ },
+ {
+ "name": "squizlabs/php_codesniffer",
+ "version": "3.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
+ "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ffced0d2c8fa8e6cdc4d695a743271fab6c38625",
+ "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625",
+ "shasum": ""
+ },
+ "require": {
+ "ext-simplexml": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "bin": [
+ "bin/phpcs",
+ "bin/phpcbf"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Greg Sherwood",
+ "role": "lead"
+ }
+ ],
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
+ "keywords": [
+ "phpcs",
+ "standards"
+ ],
+ "support": {
+ "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
+ "source": "https://github.com/squizlabs/PHP_CodeSniffer",
+ "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
+ },
+ "time": "2021-04-09T00:54:41+00:00"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "v5.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "0d639a0943822626290d169965804f79400e6a04"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/0d639a0943822626290d169965804f79400e6a04",
+ "reference": "0d639a0943822626290d169965804f79400e6a04",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Finder\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Finds files and directories via an intuitive fluent interface",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/finder/tree/v5.2.4"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-02-15T18:55:04+00:00"
+ },
+ {
+ "name": "symfony/process",
+ "version": "v5.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/process.git",
+ "reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/process/zipball/313a38f09c77fbcdc1d223e57d368cea76a2fd2f",
+ "reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-php80": "^1.15"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Process\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Executes commands in sub-processes",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/process/tree/v5.2.4"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-27T10:15:41+00:00"
+ },
+ {
+ "name": "symfony/var-dumper",
+ "version": "v5.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-dumper.git",
+ "reference": "89412a68ea2e675b4e44f260a5666729f77f668e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/89412a68ea2e675b4e44f260a5666729f77f668e",
+ "reference": "89412a68ea2e675b4e44f260a5666729f77f668e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php80": "^1.15"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<5.4.3",
+ "symfony/console": "<4.4"
+ },
+ "require-dev": {
+ "ext-iconv": "*",
+ "symfony/console": "^4.4|^5.0",
+ "symfony/process": "^4.4|^5.0",
+ "twig/twig": "^2.13|^3.0.4"
+ },
+ "suggest": {
+ "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
+ "ext-intl": "To show region name in time zone dump",
+ "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
+ },
+ "bin": [
+ "Resources/bin/var-dump-server"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions/dump.php"
+ ],
+ "psr-4": {
+ "Symfony\\Component\\VarDumper\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides mechanisms for walking through any arbitrary PHP variable",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "debug",
+ "dump"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/var-dumper/tree/v5.2.6"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-28T09:42:18+00:00"
+ },
+ {
+ "name": "theseer/tokenizer",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "75a63c33a8577608444246075ea0af0d052e452a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a",
+ "reference": "75a63c33a8577608444246075ea0af0d052e452a",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "support": {
+ "issues": "https://github.com/theseer/tokenizer/issues",
+ "source": "https://github.com/theseer/tokenizer/tree/master"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2020-07-12T23:59:07+00:00"
+ },
+ {
+ "name": "twig/twig",
+ "version": "v1.44.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "138c493c5b8ee7cff3821f80b8896d371366b5fe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/138c493c5b8ee7cff3821f80b8896d371366b5fe",
+ "reference": "138c493c5b8ee7cff3821f80b8896d371366b5fe",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "require-dev": {
+ "psr/container": "^1.0",
+ "symfony/phpunit-bridge": "^4.4.9|^5.0.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.44-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Twig_": "lib/"
+ },
+ "psr-4": {
+ "Twig\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Twig Team",
+ "role": "Contributors"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "https://twig.symfony.com",
+ "keywords": [
+ "templating"
+ ],
+ "support": {
+ "issues": "https://github.com/twigphp/Twig/issues",
+ "source": "https://github.com/twigphp/Twig/tree/v1.44.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-05T10:10:05+00:00"
+ },
+ {
+ "name": "umpirsky/twig-php-function",
+ "version": "v0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/umpirsky/twig-php-function.git",
+ "reference": "53b4b1eb0c5eacbd7d66c504b7d809c79b4bedbc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/umpirsky/twig-php-function/zipball/53b4b1eb0c5eacbd7d66c504b7d809c79b4bedbc",
+ "reference": "53b4b1eb0c5eacbd7d66c504b7d809c79b4bedbc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "twig/twig": "~1.12"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "~2.0",
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Umpirsky\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Saša Stamenković",
+ "email": "umpirsky@gmail.com"
+ }
+ ],
+ "description": "Call (almost) any PHP function from your Twig templates.",
+ "support": {
+ "issues": "https://github.com/umpirsky/twig-php-function/issues",
+ "source": "https://github.com/umpirsky/twig-php-function/tree/master"
+ },
+ "time": "2016-03-12T16:36:32+00:00"
+ },
+ {
+ "name": "webmozart/assert",
+ "version": "1.10.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozarts/assert.git",
+ "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
+ "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "conflict": {
+ "phpstan/phpstan": "<0.12.20",
+ "vimeo/psalm": "<4.6.1 || 4.6.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5.13"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.10-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Webmozart\\Assert\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": [
+ "assert",
+ "check",
+ "validate"
+ ],
+ "support": {
+ "issues": "https://github.com/webmozarts/assert/issues",
+ "source": "https://github.com/webmozarts/assert/tree/1.10.0"
+ },
+ "time": "2021-03-09T10:59:23+00:00"
+ },
+ {
+ "name": "wyrihaximus/twig-view",
+ "version": "4.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cakephp/legacy-twig-view.git",
+ "reference": "463e1a6ed493d4fe99eaeaaf39d80172b51fc0fb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cakephp/legacy-twig-view/zipball/463e1a6ed493d4fe99eaeaaf39d80172b51fc0fb",
+ "reference": "463e1a6ed493d4fe99eaeaaf39d80172b51fc0fb",
+ "shasum": ""
+ },
+ "require": {
+ "ajgl/breakpoint-twig-extension": "^0.3.0",
+ "aptoma/twig-markdown": "^2.0",
+ "asm89/twig-cache-extension": "^1.0",
+ "cakephp/cakephp": "^3.7",
+ "jasny/twig-extensions": "^1.0",
+ "php": "^5.6 || ^7.0",
+ "twig/twig": "^1.27",
+ "umpirsky/twig-php-function": "0.1"
+ },
+ "require-dev": {
+ "cakephp/bake": "^1.5",
+ "cakephp/debug_kit": "^3.0",
+ "phake/phake": "^2.3.2",
+ "phpunit/phpunit": "^5.7.14",
+ "squizlabs/php_codesniffer": "^3.4.0",
+ "wyrihaximus/phpunit-class-reflection-helpers": "dev-master"
+ },
+ "type": "cakephp-plugin",
+ "autoload": {
+ "psr-4": {
+ "WyriHaximus\\TwigView\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Cees-Jan Kiewiet",
+ "email": "ceesjank@gmail.com",
+ "homepage": "http://wyrihaximus.net/"
+ }
+ ],
+ "description": "Twig powered View for CakePHP3",
+ "keywords": [
+ "cakephp",
+ "cakephp3",
+ "twig",
+ "view"
+ ],
+ "support": {
+ "issues": "https://github.com/cakephp/legacy-twig-view/issues",
+ "source": "https://github.com/cakephp/legacy-twig-view/tree/4.4.0"
+ },
+ "time": "2021-04-06T15:42:50+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": {
+ "psy/psysh": 0
+ },
+ "prefer-stable": true,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=5.6"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.0.0"
+}
diff --git a/community_server/config/routes.php b/community_server/config/routes.php
index ec3b5fd27..5a537b9c2 100644
--- a/community_server/config/routes.php
+++ b/community_server/config/routes.php
@@ -57,12 +57,12 @@ Router::scope('/', function (RouteBuilder $routes) {
$csrf->whitelistCallback(function ($request) {
// Skip token check for API URLs.
//die($request->getParam('controller'));
- $whitelist = ['JsonRequestHandler', 'ElopageWebhook'];
+ $whitelist = ['JsonRequestHandler', 'ElopageWebhook', 'AppRequests'];
$ajaxWhitelist = ['TransactionSendCoins', 'TransactionCreations'];
-
+
foreach($whitelist as $entry) {
if($request->getParam('controller') === $entry) {
- if($entry == 'ElopageWebhook') {
+ if($entry == 'ElopageWebhook' || $entry == 'AppRequests') {
return true;
}
if($request->clientIp() == '127.0.0.1' || $request->clientIp() == 'localhost') {
@@ -110,7 +110,11 @@ Router::scope('/', function (RouteBuilder $routes) {
*/
//$routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
$routes->connect('/', ['controller' => 'Dashboard', 'action' => 'index']);
+ $routes->connect('/api/:action/*', ['controller' => 'AppRequests'], ['routeClass' => 'DashedRoute']);
+ //$routes->connect('/client', ['controller' => 'Pages', 'action' => 'display', 'js']);
$routes->connect('/server', ['controller' => 'Dashboard', 'action' => 'serverIndex']);
+ $routes->connect('/client', ['controller' => 'Pages', 'action' => 'display', 'vue']);
+ $routes->connect('/vue-dev', ['controller' => 'Pages', 'action' => 'display', 'vue-dev']);
//$routes->connect('/', 'https://gradido2.dario-rekowski.de/account', array('status' => 303));
/**
diff --git a/community_server/docu/community-server.api.md b/community_server/docu/community-server.api.md
new file mode 100644
index 000000000..6032ce0a2
--- /dev/null
+++ b/community_server/docu/community-server.api.md
@@ -0,0 +1,132 @@
+
+# community server api
+
+In this examples I assume that you use gradido with docker-compose build on your local maschine
+
+## Konto Overview
+return current account balance
+
+GET http://localhost/state-balances/ajaxGetBalance/-127182
+
+If session is valid, return:
+```json
+{"state":"success","balance":174500}
+```
+- balance: Gradido Cent, 4 Nachkommastellen (2 Reserve), 174500 = 17,45 GDD
+
+## List Transactions
+List all transactions from logged in user, currently without paging
+Ajax:
+GET http://localhost/state-balances/ajaxListTransactions/-127182/
+or
+GET http://localhost/state-balances/ajaxListTransactions/-127182/DESC
+to get transaction in descending order
+
+Antwort:
+Wenn alles okay:
+```json
+{"state":"success", "transactions":
+ [
+ {
+ "name": "Max Mustermann",
+ "email": "Maxim Mustermann",
+ "type": "send",
+ "transaction_id": 2,
+ "date": "2021-02-19T13:25:36+00:00",
+ "balance": 1920000,
+ "memo": "a piece of cake :)",
+ "pubkey": "038a6f93270dc57b91d76bf110ad3863fcb7d1b08e7692e793fcdb4467e5b6a7"
+ }
+ ],
+ "transactionExecutingCount": 0,
+ "count": 1,
+ "gdtSum": 0,
+ "timeUsed": 0.04562687873840332
+}
+```
+
+- name: name of other involved party or empty if unknown (if other party don't belong to group)
+ - if type is send, name is name of receiver
+ - if type is receive, name is name of sender
+ - if type is creation currently I use a static string ("Gradido Akademie)
+- email: optional, only if type is send or receive and other user is known
+- pubkey: optional, only if type is send or receive and other user isn't known
+- type: type of transaction
+ - creation: user has get gradidos created
+ - send: user has send another user gradidos
+ - receiver: user has received gradidos from another user
+- transaction_id: id of transaction in db, in stage2 also the hedera sequence number of transaction
+- date: date of ordering transaction (booking date)
+- balance: Gradido Cent, 4 Nachkommastellen (2 Reserve), 1920000 = 192,00 GDD
+- memo: Details about transaction
+- pubkey: optional, if other party isn't known, hexadecimal representation of 32 Byte public key of user [0-9a-f]
+
+- transactionExecutingCount: how many transaction for this user currently pending and waiting for signing
+- count: sum of finished transactions user is involved
+- gdtSum: sum of gdt of user in cent with 2 places (Nachkommastellen)
+- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
+
+## Creation Transaction
+Make a creation transaction
+With new Option set in Login-Server:
+```ini
+unsecure.allow_auto_sign_transactions = 1
+```
+transactions can be auto-signed directly with handing in transaction.
+Normally a forwarding to login-server check transactions side is neccessary to minimize security risks.
+
+POST http://localhost/transaction-creations/ajaxCreate
+```json
+{
+ "session_id" : -127182,
+ "email": "max.musterman@gmail.de",
+ "amount": 10000000,
+ "target_date":"2021-02-19T13:25:36+00:00",
+ "memo":"AGE",
+ "auto_sign": true
+}
+```
+return if everything is ok:
+```json
+{"state":"success", "timeUsed": 0.0122}
+```
+- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
+
+## Send Coins Transaction
+Make a simple GDD Transaction, send Coins from one user to other.
+With new Option set in Login-Server:
+```ini
+unsecure.allow_auto_sign_transactions = 1
+```
+transactions can be auto-signed directly with handing in transaction.
+Normally a forwarding to login-server check transactions side is neccessary to minimize security risks.
+
+POST http://localhost/transaction-send-coins/ajaxCreate
+```json
+{
+ "session_id" : -127182,
+ "amount": 2000000,
+ "email": "max.musterman@gmail.de",
+ "memo":"Thank you :)",
+ "auto_sign": true
+}
+```
+- amout: amount to transfer, 2000000 = 200,00 GDD
+- email: receiver email address, must be differ from user email
+- memo: Details about transaction
+- auto_sign: set to true to directly sign transaction if unsecure.allow_auto_sign_transactions = 1 is set
+
+return if everything is ok:
+```json
+{"state":"success", "timeUsed": 0.0122}
+```
+- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
+
+Than the transaction was created on community server, send to login-server, signed (if unsecure.allow_auto_sign_transactions = 1 and auto_sign = true)
+and send back to community server and put into db.
+After you get this answear you see the new transaction if you list transactions or call for the balance.
+
+Without auto-sign the transaction is pending on login-server and waits for the user to review it at
+http://localhost/account/checkTransactions
+
+
diff --git a/community_server/parse_proto.sh b/community_server/parse_proto.sh
index 576b99691..e6ccb451f 100755
--- a/community_server/parse_proto.sh
+++ b/community_server/parse_proto.sh
@@ -16,5 +16,5 @@
#PHP_PLUGIN="$(which grpc_php_plugin)"
#protoc --proto_path=./src/protobuf/gradido --php_out=./src/ --grpc_out=./src/ --plugin=protoc-gen-grpc=$PHP_PLUGIN ./src/protobuf/gradido/*.proto
-protoc --proto_path=./src/protobuf/gradido --php_out=./src/ ./src/protobuf/gradido/*.proto
+protoc --proto_path=./src/protobuf --php_out=./src/Model/Messages ./src/protobuf/gradido/*.proto
diff --git a/community_server/skeema/gradido_community/address_types.sql b/community_server/skeema/gradido_community/address_types.sql
new file mode 100644
index 000000000..cb5b1b943
--- /dev/null
+++ b/community_server/skeema/gradido_community/address_types.sql
@@ -0,0 +1,7 @@
+CREATE TABLE `address_types` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `name` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
+ `text` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
diff --git a/community_server/skeema/gradido_community/blockchain_types.sql b/community_server/skeema/gradido_community/blockchain_types.sql
new file mode 100644
index 000000000..bd6a12604
--- /dev/null
+++ b/community_server/skeema/gradido_community/blockchain_types.sql
@@ -0,0 +1,17 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+/**
+ * Author: einhornimmond
+ * Created: 06.04.2021
+ */
+
+CREATE TABLE `blockchain_types` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `name` varchar(45) NOT NULL,
+ `text` varchar(255) NULL,
+ `symbol` varchar(10) NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
diff --git a/community_server/skeema/gradido_community/insert/address_types.sql b/community_server/skeema/gradido_community/insert/address_types.sql
new file mode 100644
index 000000000..2a6dc00a5
--- /dev/null
+++ b/community_server/skeema/gradido_community/insert/address_types.sql
@@ -0,0 +1,2 @@
+INSERT INTO `address_types` (`id`, `name`, `text`) VALUES
+(1, 'user main', 'user main address');
diff --git a/community_server/skeema/gradido_community/insert/insert_blockchain_types.sql b/community_server/skeema/gradido_community/insert/insert_blockchain_types.sql
new file mode 100644
index 000000000..0a58e4392
--- /dev/null
+++ b/community_server/skeema/gradido_community/insert/insert_blockchain_types.sql
@@ -0,0 +1,5 @@
+INSERT INTO `blockchain_types` (`id`, `name`, `text`, `symbol`) VALUES
+(1, 'mysql', 'use mysql db as blockchain, work only with single community-server', NULL),
+(2, 'hedera', 'use hedera for transactions', 'HBAR');
+
+
diff --git a/community_server/skeema/gradido_community/insert/insert_transaction_types.sql b/community_server/skeema/gradido_community/insert/insert_transaction_types.sql
index 9dbf5b93f..02ef8374a 100644
--- a/community_server/skeema/gradido_community/insert/insert_transaction_types.sql
+++ b/community_server/skeema/gradido_community/insert/insert_transaction_types.sql
@@ -1,5 +1,10 @@
-
INSERT INTO `transaction_types` (`id`, `name`, `text`) VALUES
-(1, 'creation', 'Aktives oder Bedingungsloses Grundeinkommen.'),
-(2, 'transfer', 'Einfache Überweisung');
+(1, 'creation', 'create new gradidos for member and also for group (in development)'),
+(2, 'transfer', 'send gradidos from one member to another, also cross group transfer'),
+(3, 'group create', 'create a new group, trigger creation of new hedera topic and new blockchain on node server'),
+(4, 'group add member', 'add user to a group or move if he was already in a group'),
+(5, 'group remove member', 'remove user from group, maybe he was moved elsewhere'),
+(6, 'hedera topic create', 'create new topic on hedera'),
+(7, 'hedera topic send message', 'send consensus message over hedera topic'),
+(8, 'hedera account create', 'create new account on hedera for holding some founds with unencrypted keys');
diff --git a/community_server/skeema/gradido_community/state_group_addresses.sql b/community_server/skeema/gradido_community/state_group_addresses.sql
index 1d256f3e0..698a79b98 100644
--- a/community_server/skeema/gradido_community/state_group_addresses.sql
+++ b/community_server/skeema/gradido_community/state_group_addresses.sql
@@ -3,5 +3,6 @@ CREATE TABLE `state_group_addresses` (
`group_id` int(10) unsigned NOT NULL,
`public_key` binary(32) NOT NULL,
`address_type_id` int(10) unsigned NOT NULL,
- PRIMARY KEY (`id`)
+ PRIMARY KEY (`id`),
+ UNIQUE(`public_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
diff --git a/community_server/skeema/gradido_community/state_user_transactions.sql b/community_server/skeema/gradido_community/state_user_transactions.sql
index 272552845..5e01cac4a 100644
--- a/community_server/skeema/gradido_community/state_user_transactions.sql
+++ b/community_server/skeema/gradido_community/state_user_transactions.sql
@@ -4,6 +4,6 @@ CREATE TABLE `state_user_transactions` (
`transaction_id` int UNSIGNED NOT NULL,
`transaction_type_id` int UNSIGNED NOT NULL,
`balance` bigint(20) DEFAULT 0,
- `balance_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `balance_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
diff --git a/community_server/skeema/gradido_community/transaction_group_addaddress.sql b/community_server/skeema/gradido_community/transaction_group_addaddress.sql
index dceac273c..cb21ed99f 100644
--- a/community_server/skeema/gradido_community/transaction_group_addaddress.sql
+++ b/community_server/skeema/gradido_community/transaction_group_addaddress.sql
@@ -1,7 +1,9 @@
CREATE TABLE `transaction_group_addaddress` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `transaction_id` int(10) unsigned NOT NULL,
- `address_type_id` int(10) unsigned NOT NULL,
+ `id` int unsigned NOT NULL AUTO_INCREMENT,
+ `transaction_id` int unsigned NOT NULL,
+ `address_type_id` int unsigned NOT NULL,
+ `remove_from_group` BOOLEAN DEFAULT FALSE,
`public_key` binary(32) NOT NULL,
+ `state_user_id` int unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
diff --git a/community_server/skeema/gradido_community/transaction_send_coins.sql b/community_server/skeema/gradido_community/transaction_send_coins.sql
index f57a2175e..49423fdbc 100644
--- a/community_server/skeema/gradido_community/transaction_send_coins.sql
+++ b/community_server/skeema/gradido_community/transaction_send_coins.sql
@@ -1,9 +1,10 @@
CREATE TABLE `transaction_send_coins` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`transaction_id` int(10) unsigned NOT NULL,
- `state_user_id` int(10) unsigned NOT NULL,
+ `sender_public_key` binary(32) NOT NULL,
+ `state_user_id` int(10) unsigned DEFAULT 0,
`receiver_public_key` binary(32) NOT NULL,
- `receiver_user_id` int(10) unsigned NOT NULL,
+ `receiver_user_id` int(10) unsigned DEFAULT 0,
`amount` bigint(20) NOT NULL,
`sender_final_balance` bigint(20) NOT NULL,
PRIMARY KEY (`id`)
diff --git a/community_server/skeema/gradido_community/transaction_types.sql b/community_server/skeema/gradido_community/transaction_types.sql
index 87492e1fe..a3e6779d9 100644
--- a/community_server/skeema/gradido_community/transaction_types.sql
+++ b/community_server/skeema/gradido_community/transaction_types.sql
@@ -1,6 +1,6 @@
CREATE TABLE `transaction_types` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(24) COLLATE utf8mb4_unicode_ci NOT NULL,
+ `name` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
`text` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
diff --git a/community_server/skeema/gradido_community/transactions.sql b/community_server/skeema/gradido_community/transactions.sql
index 0e8c00ce6..8641f0057 100644
--- a/community_server/skeema/gradido_community/transactions.sql
+++ b/community_server/skeema/gradido_community/transactions.sql
@@ -2,8 +2,9 @@ CREATE TABLE `transactions` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`state_group_id` int(10) unsigned DEFAULT NULL,
`transaction_type_id` int(10) unsigned NOT NULL,
- `tx_hash` binary(32) DEFAULT NULL,
+ `tx_hash` binary(48) DEFAULT NULL,
`memo` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`received` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `blockchain_type_id` bigint(20) unsigned NOT NULL DEFAULT 1,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
diff --git a/community_server/src/Controller/AddressTypesController.php b/community_server/src/Controller/AddressTypesController.php
index 348a8e9e6..9b13a7720 100644
--- a/community_server/src/Controller/AddressTypesController.php
+++ b/community_server/src/Controller/AddressTypesController.php
@@ -2,7 +2,6 @@
namespace App\Controller;
use App\Controller\AppController;
-use Cake\I18n\Number;
/**
* AddressTypes Controller
@@ -35,7 +34,7 @@ class AddressTypesController extends AppController
public function view($id = null)
{
$addressType = $this->AddressTypes->get($id, [
- 'contain' => ['StateGroupAddresses', 'TransactionGroupAddaddress']
+ 'contain' => ['StateGroupAddresses', 'TransactionGroupAddaddress'],
]);
$this->set('addressType', $addressType);
@@ -71,7 +70,7 @@ class AddressTypesController extends AppController
public function edit($id = null)
{
$addressType = $this->AddressTypes->get($id, [
- 'contain' => []
+ 'contain' => [],
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$addressType = $this->AddressTypes->patchEntity($addressType, $this->request->getData());
diff --git a/community_server/src/Controller/AppController.php b/community_server/src/Controller/AppController.php
index 83ec01572..98a690bd1 100644
--- a/community_server/src/Controller/AppController.php
+++ b/community_server/src/Controller/AppController.php
@@ -35,6 +35,7 @@ class AppController extends Controller
{
var $loginServerUrl = '';
+ var $blockchainType = 'mysql';
/**
* Initialization hook method.
*
@@ -91,12 +92,11 @@ class AppController extends Controller
$stateBalancesTable = TableRegistry::getTableLocator()->get('stateBalances');
$stateBalanceQuery = $stateBalancesTable
->find('all')
- ->select('amount')
->contain(false)
->where(['state_user_id' => $state_user_id]);
if ($stateBalanceQuery->count() == 1) {
//var_dump($stateBalanceEntry->first());
- $session->write('StateUser.balance', $stateBalanceQuery->first()->amount);
+ $session->write('StateUser.balance', $stateBalanceQuery->first()->decay);
//echo "stateUser.balance: " . $session->read('StateUser.balance');
}
}
@@ -137,16 +137,42 @@ class AppController extends Controller
} else {
$this->loginServerUrl = Router::url('/', true);
}
+ /*
+ *
+ * 'GradidoBlockchain' => [
+ * // type:
+ * // - mysql: centralized blockchain in mysql db, no cross group transactions
+ * // - hedera: send transaction over hedera
+ * 'type' => 'hedera',
+ * // gradido nodes with blockchain (if type != mysql)
+ * 'nodes' => [
+ * ['host' => 'http://192.168.178.225', 'port' => 13702]
+ * ]
+ * ],
+ */
+ $blockchain = Configure::read('GradidoBlockchain');
+ if($blockchain && isset($blockchain['type'])) {
+ $this->blockchainType = $blockchain['type'];
+ }
}
- protected function requestLogin($session_id = 0, $redirect = true)
+ protected function requestLogin($sessionId = 0, $redirect = true)
{
$session = $this->getRequest()->getSession();
// check login
// disable encryption for cookies
- //$this->Cookie->configKey('User', 'encryption', false);
- if(!$session_id) {
- $session_id = intval($this->request->getCookie('GRADIDO_LOGIN', ''));
+ $session_id = 0;
+ $php_session_id = 0;
+ if($session->check('session_id')) {
+ $php_session_id = intval($session->read('session_id'));
+ }
+ $cookie_session_id = intval($this->request->getCookie('GRADIDO_LOGIN', ''));
+ if($php_session_id != 0) {
+ $session_id = $php_session_id;
+ } else if($cookie_session_id != 0) {
+ $session_id = $cookie_session_id;
+ } else {
+ $session_id = $sessionId;
}
$ip = $this->request->clientIp();
if (!$session->check('client_ip')) {
@@ -158,14 +184,16 @@ class AppController extends Controller
if ($session_id != 0) {
$userStored = $session->read('StateUser');
-
+
$transactionPendings = $session->read('Transactions.pending');
- $transactionExecutings = $session->read('Transactions.executing');
-
+ $transactionExecutings = $session->read('Transactions.executing');
+ $transaction_can_signed = $session->read('Transactions.can_signed');
+
if ($session->read('session_id') != $session_id ||
( $userStored && (!isset($userStored['id']) || !$userStored['email_checked'])) ||
intval($transactionPendings) > 0 ||
- intval($transactionExecutings) > 0) {
+ intval($transactionExecutings) > 0 ||
+ intval($transaction_can_signed > 0)) {
$http = new Client();
try {
@@ -189,9 +217,11 @@ class AppController extends Controller
//var_dump($json);
$transactionPendings = $json['Transactions.pending'];
$transactionExecuting = $json['Transactions.executing'];
+ $transaction_can_signed = $json['Transactions.can_signed'];
//echo "read transaction pending: $transactionPendings
";
$session->write('Transactions.pending', $transactionPendings);
$session->write('Transactions.executing', $transactionExecuting);
+ $session->write('Transactions.can_signed', $transaction_can_signed);
$session->write('session_id', $session_id);
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
@@ -200,12 +230,15 @@ class AppController extends Controller
$stateUserQuery = $stateUserTable
->find('all')
->where(['public_key' => $public_key_bin])
- ->contain(['StateBalances']);
+ ->contain('StateBalances', function ($q) {
+ return $q->order(['record_date' => 'DESC'])
+ ->limit(1);
+ });
if ($stateUserQuery->count() == 1) {
$stateUser = $stateUserQuery->first();
if ($stateUser->first_name != $json['user']['first_name'] ||
$stateUser->last_name != $json['user']['last_name'] ||
- $stateUser->disabled != intval($json['user']['disabled']) ||
+ $stateUser->disabled != $json['user']['disabled'] ||
//$stateUser->username != $json['user']['username'] ||
// -> throws error
$stateUser->email != $json['user']['email']
@@ -221,7 +254,8 @@ class AppController extends Controller
}
//var_dump($stateUser);
if (count($stateUser->state_balances) > 0) {
- $session->write('StateUser.balance', $stateUser->state_balances[0]->amount);
+
+ $session->write('StateUser.balance', $stateUser->state_balances[0]->decay);
}
$session->write('StateUser.id', $stateUser->id);
//echo $stateUser['id'];
@@ -258,6 +292,9 @@ class AppController extends Controller
$this->Flash->error(__('Konto ist nicht aktiviert!'));
}
//die(json_encode($json));
+ if(preg_match('/client ip/', $json['msg'])) {
+ return $this->redirect($this->loginServerUrl . 'account/error500/ipError', 303);
+ }
return $this->redirect($this->loginServerUrl . 'account/', 303);
}
}
diff --git a/community_server/src/Controller/AppRequestsController.php b/community_server/src/Controller/AppRequestsController.php
new file mode 100644
index 000000000..c7ac060e9
--- /dev/null
+++ b/community_server/src/Controller/AppRequestsController.php
@@ -0,0 +1,274 @@
+loadComponent('JsonRequestClient');
+ //$this->loadComponent('JsonRpcRequestClient');
+ //$this->Auth->allow(['add', 'edit']);
+ $this->Auth->allow(['index', 'sendCoins', 'createCoins']);
+ }
+
+
+ public function index()
+ {
+ if($this->request->is('get')) {
+ $method = $this->request->getQuery('method');
+ switch($method) {
+
+ }
+ return $this->returnJson(['state' => 'error', 'msg' => 'unknown method for get', 'details' => $method]);
+ }
+ else if($this->request->is('post')) {
+ $jsonData = $this->request->input('json_decode');
+ //var_dump($jsonData);
+ if($jsonData == NULL || !isset($jsonData->method)) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'parameter error']);
+ }
+ $method = $jsonData->method;
+
+ switch($method) {
+
+ }
+ return $this->returnJson(['state' => 'error', 'msg' => 'unknown method for post', 'details' => $method]);
+ }
+ return $this->returnJson(['state' => 'error', 'msg' => 'no post or get']);
+ }
+
+ private function checkAndCopyRequiredFields($fields, &$param, $data = null) {
+ if($data == null) {
+ $data = $this->request->input('json_decode');
+ }
+ foreach($fields as $field) {
+ if(is_array($field)) {
+ $one_exist = false;
+ foreach($field as $oneField) {
+ if(isset($data[$oneField])) {
+ $param[$oneField] = $data[$oneField];
+ $one_exist = true;
+ break;
+ }
+ }
+ if(!$one_exist) {
+ return ['state' => 'error', 'msg' => 'missing field of set', 'details' => $field];
+ }
+ } else {
+ if(!isset($data[$field])) {
+ return ['state' => 'error', 'msg' => 'missing field', 'details' => $field . ' not found'];
+ } else {
+ $param[$field] = $data[$field];
+ }
+ }
+ }
+ return true;
+ }
+
+ private function rewriteKeys(&$data, $replaceKeys)
+ {
+ foreach(array_keys($replaceKeys) as $key) {
+ $newKey = $replaceKeys[$key];
+ if(isset($data[$key])) {
+ $data[$newKey] = $data[$key];
+ unset($data[$key]);
+ }
+ }
+ }
+
+ private function parseParameterForCreateTransaction(&$param, $data = null)
+ {
+ if($data == null) {
+ $data = $this->request->input('json_decode');
+ }
+ $session_id = 0;
+ if(isset($data['session_id'])) {
+ $session_id = $data['session_id'];
+ }
+ $login_request_result = $this->requestLogin($session_id, false);
+ if($login_request_result !== true) {
+ return $login_request_result;
+ }
+ $session = $this->getRequest()->getSession();
+ $param['session_id'] = $session->read('session_id');
+ $param['blockchain_type'] = $this->blockchainType;
+
+ $this->rewriteKeys($data, ['email' => 'target_email', 'username' => 'target_username', 'pubkey' => 'target_pubkey']);
+ $required_fields = $this->checkAndCopyRequiredFields(['amount', ['target_email', 'target_username', 'target_pubkey']], $param, $data);
+ if($required_fields !== true) {
+ return $required_fields;
+ }
+
+ if(intval($param['amount']) <= 0) {
+ return ['state' => 'error', 'msg' => 'amount is invalid', 'details' => $param['amount']];
+ }
+
+ if(isset($data['memo'])) {
+ $param['memo'] = $data['memo'];
+ }
+
+ if(isset($data['auto_sign'])) {
+ $param['auto_sign'] = boolval($data['auto_sign']);
+ }
+
+ return true;
+ }
+
+ public function sendCoins()
+ {
+ /*
+ * {
+ "session_id" : -127182,
+ "amount": 2000000,
+ "email": "max.musterman@gmail.de",
+ "memo":"Thank you :)",
+ "group": "gdd1",
+ "auto_sign": true
+ */
+ if(!$this->request->is('post')) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'no post']);
+ }
+ $data = $this->request->input('json_decode');
+ $params = [];
+ $result = $this->parseParameterForCreateTransaction($params, $data);
+ if($result !== true) {
+ return $this->returnJson($result);
+ }
+ $required_fields = $this->checkAndCopyRequiredFields(['target_date'], $params, $data);
+ if($required_fields !== true) {
+ return $this->returnJson($required_fields);
+ }
+ $params['transaction_type'] = 'transfer';
+
+ $requestAnswear = $this->JsonRequestClient->sendRequest(json_encode($params), '/createTransaction');
+
+
+ if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) {
+ $session = $this->getRequest()->getSession();
+ $pendingTransactionCount = $session->read('Transactions.pending');
+ if($pendingTransactionCount == null) {
+ $pendingTransactionCount = 1;
+ } else {
+ $pendingTransactionCount++;
+ }
+ $session->write('Transactions.pending', $pendingTransactionCount);
+ //echo "pending: " . $pendingTransactionCount;
+ return $this->returnJson(['state' => 'success']);
+ } else {
+
+ /*
+ * if request contain unknown parameter format, shouldn't happen't at all
+ * {"state": "error", "msg": "parameter format unknown"}
+ * if json parsing failed
+ * {"state": "error", "msg": "json exception", "details":"exception text"}
+ * if session_id is zero or not set
+ * {"state": "error", "msg": "session_id invalid"}
+ * if session id wasn't found on login server, if server was restartet or user logged out (also per timeout, default: 15 minutes)
+ * {"state": "error", "msg": "session not found"}
+ * if session hasn't active user, shouldn't happen't at all, login-server should be checked if happen
+ * {"state": "code error", "msg":"user is zero"}
+ * if transaction type not known
+ * {"state": "error", "msg":"transaction_type unknown"}
+ * if receiver wasn't known to Login-Server
+ * {"state": "not found", "msg":"receiver not found"}
+ * if receiver account disabled, and therefor cannto receive any coins
+ * {"state": "disabled", "msg":"receiver is disabled"}
+ * if transaction was okay and will be further proccessed
+ * {"state":"success"}
+ */
+ $answear_data = $requestAnswear['data'];
+ return $this->returnJson($answear_data);
+
+ }
+
+ }
+
+ public function createCoins()
+ {
+ /*
+ * "session_id" : -127182,
+ * "email": "max.musterman@gmail.de",
+ * "amount": 10000000,
+ * "target_date":"2021-02-19T13:25:36+00:00",
+ * "memo":"AGE",
+ * "auto_sign": true
+ */
+ if(!$this->request->is('post')) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'no post']);
+ }
+ $data = $this->request->input('json_decode');
+ $params = [];
+ $result = $this->parseParameterForCreateTransaction($params, $data);
+ if($result !== true) {
+ return $this->returnJson($result);
+ }
+ $required_fields = $this->checkAndCopyRequiredFields(['target_date'], $params, $data);
+ if($required_fields !== true) {
+ return $this->returnJson($required_fields);
+ }
+ $params['transaction_type'] = 'creation';
+
+ $requestAnswear = $this->JsonRequestClient->sendRequest(json_encode($params), '/createTransaction');
+
+ if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) {
+ $session = $this->getRequest()->getSession();
+ $pendingTransactionCount = $session->read('Transactions.pending');
+ if($pendingTransactionCount == null) {
+ $pendingTransactionCount = 1;
+ } else {
+ $pendingTransactionCount++;
+ }
+ $session->write('Transactions.pending', $pendingTransactionCount);
+ //echo "pending: " . $pendingTransactionCount;
+ return $this->returnJson(['state' => 'success']);
+ } else {
+
+ /*
+ * if request contain unknown parameter format, shouldn't happen't at all
+ * {"state": "error", "msg": "parameter format unknown"}
+ * if json parsing failed
+ * {"state": "error", "msg": "json exception", "details":"exception text"}
+ * if session_id is zero or not set
+ * {"state": "error", "msg": "session_id invalid"}
+ * if session id wasn't found on login server, if server was restartet or user logged out (also per timeout, default: 15 minutes)
+ * {"state": "error", "msg": "session not found"}
+ * if session hasn't active user, shouldn't happen't at all, login-server should be checked if happen
+ * {"state": "code error", "msg":"user is zero"}
+ * if transaction type not known
+ * {"state": "error", "msg":"transaction_type unknown"}
+ * if receiver wasn't known to Login-Server
+ * {"state": "not found", "msg":"receiver not found"}
+ * if receiver account disabled, and therefor cannto receive any coins
+ * {"state": "disabled", "msg":"receiver is disabled"}
+ * if transaction was okay and will be further proccessed
+ * {"state":"success"}
+ */
+ $answear_data = $requestAnswear['data'];
+ return $this->returnJson($answear_data);
+
+ }
+
+ }
+
+ private function acquireAccessToken($session_id)
+ {
+
+ }
+
+}
+
\ No newline at end of file
diff --git a/community_server/src/Controller/BlockchainTypesController.php b/community_server/src/Controller/BlockchainTypesController.php
new file mode 100644
index 000000000..2a94037df
--- /dev/null
+++ b/community_server/src/Controller/BlockchainTypesController.php
@@ -0,0 +1,106 @@
+paginate($this->BlockchainTypes);
+
+ $this->set(compact('blockchainTypes'));
+ }
+
+ /**
+ * View method
+ *
+ * @param string|null $id Blockchain Type id.
+ * @return \Cake\Http\Response|null
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
+ */
+ public function view($id = null)
+ {
+ $blockchainType = $this->BlockchainTypes->get($id, [
+ 'contain' => [],
+ ]);
+
+ $this->set('blockchainType', $blockchainType);
+ }
+
+ /**
+ * Add method
+ *
+ * @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
+ */
+ public function add()
+ {
+ $blockchainType = $this->BlockchainTypes->newEntity();
+ if ($this->request->is('post')) {
+ $blockchainType = $this->BlockchainTypes->patchEntity($blockchainType, $this->request->getData());
+ if ($this->BlockchainTypes->save($blockchainType)) {
+ $this->Flash->success(__('The blockchain type has been saved.'));
+
+ return $this->redirect(['action' => 'index']);
+ }
+ $this->Flash->error(__('The blockchain type could not be saved. Please, try again.'));
+ }
+ $this->set(compact('blockchainType'));
+ }
+
+ /**
+ * Edit method
+ *
+ * @param string|null $id Blockchain Type id.
+ * @return \Cake\Http\Response|null Redirects on successful edit, renders view otherwise.
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
+ */
+ public function edit($id = null)
+ {
+ $blockchainType = $this->BlockchainTypes->get($id, [
+ 'contain' => [],
+ ]);
+ if ($this->request->is(['patch', 'post', 'put'])) {
+ $blockchainType = $this->BlockchainTypes->patchEntity($blockchainType, $this->request->getData());
+ if ($this->BlockchainTypes->save($blockchainType)) {
+ $this->Flash->success(__('The blockchain type has been saved.'));
+
+ return $this->redirect(['action' => 'index']);
+ }
+ $this->Flash->error(__('The blockchain type could not be saved. Please, try again.'));
+ }
+ $this->set(compact('blockchainType'));
+ }
+
+ /**
+ * Delete method
+ *
+ * @param string|null $id Blockchain Type id.
+ * @return \Cake\Http\Response|null Redirects to index.
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
+ */
+ public function delete($id = null)
+ {
+ $this->request->allowMethod(['post', 'delete']);
+ $blockchainType = $this->BlockchainTypes->get($id);
+ if ($this->BlockchainTypes->delete($blockchainType)) {
+ $this->Flash->success(__('The blockchain type has been deleted.'));
+ } else {
+ $this->Flash->error(__('The blockchain type could not be deleted. Please, try again.'));
+ }
+
+ return $this->redirect(['action' => 'index']);
+ }
+}
diff --git a/community_server/src/Controller/Component/JsonRequestClientComponent.php b/community_server/src/Controller/Component/JsonRequestClientComponent.php
index 66e65e3bb..09856d7e2 100644
--- a/community_server/src/Controller/Component/JsonRequestClientComponent.php
+++ b/community_server/src/Controller/Component/JsonRequestClientComponent.php
@@ -15,7 +15,7 @@ use Cake\Core\Configure;
class JsonRequestClientComponent extends Component
{
- public function sendTransaction($session_id, $base64Message, $user_balance = 0, $auto_sign = false) {
+ public function sendTransaction($session_id, $base64Message, $user_balance = 0, $auto_sign = false, $blockchain_type = 'mysql') {
if(!is_numeric($session_id)) {
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'session_id isn\'t numeric'];
}
@@ -36,11 +36,17 @@ class JsonRequestClientComponent extends Component
'session_id' => $session_id,
'transaction_base64' => $base64Message,
'balance' => $user_balance,
- 'auto_sign' => $auto_sign
+ 'auto_sign' => $auto_sign,
+ 'blockchain_type' => $this->blockchainType
]), '/checkTransaction');
}
+ public function findePublicKeyForEmailHash($emailHash) {
+ //'ask' = ['account_publickey' => '']
+ $results = $this->sendRequestLoginServerNeighbors(json_encode(['ask' => ['account_publickey' => $emailHash]]), 'search');
+ }
+
public function getRunningUserTasks($email)
{
if($email == "") {
@@ -122,6 +128,39 @@ class JsonRequestClientComponent extends Component
return ['state' => 'success', 'data' => $json];
}
+ public function sendRequestLoginServerNeighbors($transactionBody, $url) {
+
+ $http = new Client();
+ if(!Configure::check('NeighborLoginServers')) {
+ return ['state' => 'warning', 'msg' => 'no neighbor server configured'];
+ }
+ $nServers = Configure::read('NeighborLoginServers');
+ $results = ['errors' => [], 'data' => []];
+ foreach($nServers as $nServer) {
+ $full_url = $nServer['host'] . ':' . $nServer['port'] . '/' . $url;
+ $response = $http->post($full_url, $transactionBody, ['type' => 'json']);
+ $responseStatus = $response->getStatusCode();
+ if($responseStatus != 200) {
+ $results['errors'][] = [
+ 'state' => 'error',
+ 'type' => 'request error',
+ 'msg' => 'server response status code isn\'t 200',
+ 'details' => $responseStatus,
+ 'fullUrl' => $full_url
+ ];
+ continue;
+ }
+ $json = $response->getJson();
+ if($json == null) {
+ //$responseType = $response->getType();
+ $results['errors'][] = ['state' => 'error', 'type' => 'request error', 'msg' => 'server response isn\'t valid json'];
+ continue;
+ }
+ $results['data'][] = $json;
+ }
+ return $results;
+ }
+
static public function getLoginServerUrl()
{
$loginServer = Configure::read('LoginServer');
diff --git a/community_server/src/Controller/Component/JsonRpcRequestClientComponent.php b/community_server/src/Controller/Component/JsonRpcRequestClientComponent.php
index 5ccf6d898..504fc8fdd 100644
--- a/community_server/src/Controller/Component/JsonRpcRequestClientComponent.php
+++ b/community_server/src/Controller/Component/JsonRpcRequestClientComponent.php
@@ -41,7 +41,15 @@ class JsonRpcRequestClientComponent extends Component
public function sendRequest($message) {
$http = new Client();
- $response = $http->post($this->getGradidoNodeUrl(), $message, ['type' => 'json']);
+ try {
+ $url = $this->pickGradidoNodeUrl();
+ if(is_array($url)) {
+ return $url;
+ }
+ $response = $http->post($url, $message, ['type' => 'json']);
+ } catch(Exception $e) {
+ return ['state' => 'error', 'type' => 'http exception', 'details' => $e->getMessage()];
+ }
$responseStatus = $response->getStatusCode();
if($responseStatus != 200) {
return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response status code isn\'t 200', 'details' => $responseStatus];
@@ -55,14 +63,18 @@ class JsonRpcRequestClientComponent extends Component
//$responseType = $response->getType();
return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response isn\'t valid json'];
}
- return $json;
+ return $json['result'];
//return ['state' => 'success', 'data' => $json];
}
- static public function getGradidoNodeUrl()
+ static public function pickGradidoNodeUrl()
{
- $gradidoNode = Configure::read('GradidoNode');
- return $gradidoNode['host'] . ':' . $gradidoNode['port'];
+ $gradidoNodes = Configure::read('GradidoBlockchain.nodes');
+ if(count($gradidoNodes) == 0) {
+ return ['state' => 'error', 'msg' => 'no gradido nodes in config'];
+ }
+ $i = rand(0, count($gradidoNodes)-1);
+ return $gradidoNodes[$i]['host'] . ':' . $gradidoNodes[$i]['port'];
}
diff --git a/community_server/src/Controller/ErrorController.php b/community_server/src/Controller/ErrorController.php
index 43bd2fb52..c5421a24d 100644
--- a/community_server/src/Controller/ErrorController.php
+++ b/community_server/src/Controller/ErrorController.php
@@ -54,7 +54,7 @@ class ErrorController extends AppController
public function beforeRender(Event $event)
{
parent::beforeRender($event);
-
+ $this->RequestHandler->renderAs($this, 'json');
$this->viewBuilder()->setTemplatePath('Error');
}
diff --git a/community_server/src/Controller/JsonRequestHandlerController.php b/community_server/src/Controller/JsonRequestHandlerController.php
index e5823397e..ba68f2b5a 100644
--- a/community_server/src/Controller/JsonRequestHandlerController.php
+++ b/community_server/src/Controller/JsonRequestHandlerController.php
@@ -10,6 +10,7 @@ use Cake\Core\Configure;
use Model\Transactions\TransactionTransfer;
use Model\Transactions\Transaction;
+use Model\Transactions\Record;
/*!
* @author: Dario Rekowski#
*
@@ -24,6 +25,7 @@ class JsonRequestHandlerController extends AppController {
{
parent::initialize();
$this->loadComponent('JsonRequestClient');
+ $this->loadComponent('JsonRpcRequestClient');
//$this->Auth->allow(['add', 'edit']);
$this->Auth->allow('index');
}
@@ -58,28 +60,277 @@ class JsonRequestHandlerController extends AppController {
case 'checkUser': return $this->checkUser($jsonData->email, $jsonData->last_name);
case 'getUsers' : return $this->getUsers($jsonData->page, $jsonData->limit);
case 'getUserBalance': return $this->getUserBalance($jsonData->email, $jsonData->last_name);
- case 'errorInTransaction': return $this->errorInTransaction($jsonData->created, $jsonData->transactionGenericHash, $jsonData->error, $jsonData->errorMessage);
+ case 'errorInTransaction': return $this->errorInTransaction($jsonData);
+ case 'updateReadNode': return $this->updateReadNode();
+ case 'addUser' : return $this->addUser($jsonData->user);
}
return $this->returnJson(['state' => 'error', 'msg' => 'unknown method for post', 'details' => $method]);
}
return $this->returnJson(['state' => 'error', 'msg' => 'no post or get']);
}
-
+
+ private function addUser($newUser)
+ {
+ $stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers');
+ $entity = $stateUsersTable->newEntity();
+ $required_fields = ['first_name', 'last_name', 'email', 'public_key', 'disabled'];
+ foreach($required_fields as $required_field) {
+ if(!isset($newUser->$required_field)) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'missing required field in addUser', 'details' => $required_field]);
+ }
+ if('public_key' == $required_field) {
+ $entity->$required_field = hex2bin($newUser->public_hex);
+ } else {
+ $entity->$required_field = $newUser->$required_field;
+ }
+ }
+ if($stateUsersTable->save($entity)) {
+ return $this->returnJson(['state' => 'success']);
+ } else {
+ return $this->returnJson(['state' => 'error', 'msg' => 'error saving state_user', 'details' => $entity->getErrors()]);
+ }
+ }
+
+ // Called from login server like a cron job every 10 minutes or after sending transaction to hedera
+ private function updateReadNode()
+ {
+ $this->autoRender = false;
+ $response = $this->response->withType('application/json');
+
+ $transactionsTable = TableRegistry::getTableLocator()->get('Transactions');
+ $last_transaction_query = $transactionsTable->find('all')->order(['id' => 'DESC']);
+ $last_transaction_id = 0;
+ if(!$last_transaction_query->isEmpty()) {
+ $last_transaction_id = $last_transaction_query->first()->id;
+ }
+ $last_known_sequence_number = $last_transaction_id;
+
+ if($last_transaction_query->count() < $last_transaction_id) {
+ $last_transaction_id = $last_transaction_query->count();
+ }
+ //$last_transaction_id = 0;
+
+
+ $group_alias = Configure::read('GroupAlias');
+ $result = (array)$this->JsonRpcRequestClient->request('getTransactions', ['groupAlias' => $group_alias, 'lastKnownSequenceNumber' => $last_transaction_id]);
+ if(isset($result['state']) && $result['state'] == 'error') {
+ return $this->returnJson(['state' => 'error', 'msg' => 'jsonrpc error', 'details' => ['return' => $result, 'groupAlias' => $group_alias]]);
+ }
+ /* example
+ $result = json_decode("[
+ {
+ \"record_type\":\"GRADIDO_TRANSACTION\",
+ \"transaction\":{
+ \"version_number\":1,
+ \"signature\":{
+ \"pubkey\":\"2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b\",
+ \"signature\":\"aed6725baacabf903e51f92503d49fa7e6b93c6402d56d9e3784be9a3366a77459213d858af46b579287aba8b1b63d206febce18bc80cec6fa63da6289e56403\"
+ },
+ \"signature_count\":1,
+ \"hedera_transaction\":{
+ \"consensusTimestamp\":{
+ \"seconds\":1604392811,
+ \"nanos\":172812
+ },
+ \"runningHash\":\"f9ccf04137be418c3117a28bb5add6dced9745bcab74b7a2f46c182c8c98eeabf0127c131d15ebea7d0ac376f5d2de45\",
+ \"sequenceNumber\":94,
+ \"runningHashVersion\":3
+ },
+ \"transaction_type\":\"ADD_USER\",
+ \"add_user\":{
+ \"user\":\"2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b\"
+ },
+ \"result\":\"result\",
+ \"parts\":1,
+ \"memo\":\"\"
+ }
+ },
+ {
+ \"record_type\":\"GRADIDO_TRANSACTION\",
+ \"transaction\":{
+ \"version_number\":1,
+ \"signature\":{
+ \"pubkey\":\"8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d\",
+ \"signature\":\"3134adcd6cbccee17c2db398f91b6b6bdd098b6306fb2fa213eb9eb5a322af9078acca4d8b0383d4e906f3139eb3369e7c1ef0f3ac5fec724be0d085ba44af0b\"
+ },
+ \"signature_count\":2,
+ \"hedera_transaction\":{
+ \"consensusTimestamp\":{
+ \"seconds\":1604392886,
+ \"nanos\":1528
+ },
+ \"runningHash\":\"e1df5526331e3def11d6b652b8f248d20c250739b6eb98f1fe7b338901753d9d573a14601ba84f61318a48940b3c237a\",
+ \"sequenceNumber\":95,
+ \"runningHashVersion\":3
+ },
+ \"transaction_type\":\"ADD_USER\",
+ \"add_user\":{
+ \"user\":\"8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d\"
+ },
+ \"result\":\"result\",
+ \"parts\":2,
+ \"memo\":\"\"
+ }
+ },
+ {
+ \"record_type\":\"SIGNATURES\",
+ \"signature\":[
+ {
+ \"pubkey\":\"2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b\",
+ \"signature\":\"401717e768617c0f3311931c34a61e66ab362599a0e2a48ae7c4955645aec6573773985dafb84a11bfaf2bc12140c30b2f8c8ee094bc35d609bc56d15b4e9f04\"
+ }
+ ]
+ },
+ {
+ \"record_type\": \"GRADIDO_TRANSACTION\",
+ \"transaction\":{
+ \"version_number\":1,
+ \"signature\":{
+ \"pubkey\":\"2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b\",
+ \"signature\":\"99665dee9f2b475e426a2f449d0dae61924f6cf025903666ff72f2c7ef1af27523ebcd5fb684d17813fe7906b2f8cfe5ef4bdbb264ebf3ef80363491d9b86807\"
+ },
+ \"signature_count\":1,
+ \"hedera_transaction\":{
+ \"consensusTimestamp\":{
+ \"seconds\":1604392904,
+ \"nanos\":798541
+ },
+ \"runningHash\":\"f1fd03610a9788e9bac01e1efb8b99bafae450f9088cb940db954842e0799235c57d842be83d998e6c21786f77f967a7\",
+ \"sequenceNumber\":96,
+ \"runningHashVersion\":3
+ },
+ \"transaction_type\":\"GRADIDO_CREATION\",
+ \"gradido_creation\":{
+ \"user\":\"8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d\",
+ \"new_balance\":10000000,
+ \"prev_transfer_rec_num\":0,
+ \"amount\":10000000
+ },
+ \"result\":\"result\",
+ \"parts\":1,
+ \"memo\":\"\"
+ }
+ },
+ {
+ \"record_type\": \"GRADIDO_TRANSACTION\",
+ \"transaction\":{
+ \"version_number\":1,
+ \"signature\":{
+ \"pubkey\":\"8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d\",
+ \"signature\":\"90125e0cfce61397d50ed9ba6c5df4cd4e0cf6fee8b10c70fee2898765982570d9a1208c222981429ae3c229e3fd36c2bf2333518cd0a4f0515937822e499d0b\"
+ },
+ \"signature_count\":1,
+ \"hedera_transaction\":{
+ \"consensusTimestamp\":{
+ \"seconds\":1604392929,
+ \"nanos\":52539
+ },
+ \"runningHash\":\"a4be8f54be4f806b61d31f6bd770d7742822f14f03ffe09c07f08bac3031a06d12de5e38fec5c307149c7faf6e9879b8\",
+ \"sequenceNumber\":97,
+ \"runningHashVersion\":3
+ },
+ \"transaction_type\":\"LOCAL_TRANSFER\",
+ \"local_transfer\":{
+ \"sender\":{
+ \"user\":\"8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d\",
+ \"new_balance\":9825500,
+ \"prev_transfer_rec_num\":0
+ },
+ \"receiver\":{
+ \"user\":\"2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b\",
+ \"new_balance\":174500,
+ \"prev_transfer_rec_num\":0
+ },
+ \"amount\":174500
+ },
+ \"result\":\"result\",
+ \"parts\":1,
+ \"memo\":\"\"
+ }
+ }
+]", true);*/
+ $part_count = -1;
+ $temp_record = new Record;
+ $errors = [];
+ foreach($result['blocks'] as $_record) {
+ if(is_string($_record)) continue;
+ $parse_result = $temp_record->parseRecord($_record);
+
+ if($parse_result == true) {
+ $sequenceNumber = $temp_record->getSequenceNumber();
+ if($part_count == -1) {
+ $part_count = $temp_record->getPartCount();
+ }
+ $part_count--;
+
+ if($part_count == 0) {
+ if($sequenceNumber > $last_known_sequence_number) {
+ $finalize_result = $temp_record->finalize();
+ if($finalize_result !== true) {
+ $errors[] = ['msg' => 'error in finalize', 'record' => $_record, 'details' => $finalize_result, 'sequenceNumber' => $sequenceNumber];
+ }
+ }
+
+ $temp_record = new Record;
+ $part_count = -1;
+ }
+ } else {
+ $temp_record = new Record;
+ $part_count = -1;
+ $errors[] = ['msg' => 'error in parse record', 'record' => $_record, 'details' => $parse_result];
+ }
+ }
+ if(count($errors)) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'error in parsing records', 'details' => $errors]);
+ }
+ return $this->returnJson(['state' => 'success']);
+ }
+
+ /*
+ * payload.set("created", created);
+ * payload.set("id", task_model->getID());
+ * payload.set("type", task_model->getTaskTypeString());
+ * payload.set("public_key", user_model->getPublicKeyHex());
+ * payload.set("error", error);
+ * payload.set("errorMessage", errorDetails);
+ */
//! \param $transactionCreated creation of transaction in timestamp in seconds
//! -1 if transaction couldn't decode
//! \param $transactionBodyBase64Sha256 generic hash from transaction body serialized and converted to base64
//! using sodium_crypto_generichash to calculate
// hash also in base64 format
//! \param $error short error name in user language
- //! \param $errorDetails more detailed error message in user language
- private function errorInTransaction($transactionCreated, $transactionBodyBase64GenericHash, $error, $errorDetails) {
- /*
- * payload.set("created", created);
- * payload.set("id", task_model->getID());
- * payload.set("public_key", user_model->getPublicKeyHex());
- * payload.set("error", error);
- * payload.set("errorMessage", errorDetails);
- */
+ //! \param $errorDetails more detailed error message in user language
+ private function errorInTransaction($jsonData) {
+ $stateErrorTable = TableRegistry::getTableLocator()->get('StateErrors');
+ $stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers');
+ $transactionTypesTable = TableRegistry::getTableLocator()->get('TransactionTypes');
+ $stateError = $stateErrorTable->newEntity();
+ //
+ $pubkey = hex2bin($jsonData->public_key);
+ $user_query = $stateUsersTable->find('all')->select(['id'])->where(['public_key' => $pubkey]);
+ if($user_query->count() != 1) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'user not found', 'details' => 'user pubkey hex:' . $jsonData->public_key]);
+ }
+ $stateError->state_user_id = $user_query->first()->id;
+ //$stateError->transaction_type_id
+ // TODO:
+ // - show state errors in navi_notify.ctp
+ $transaction_type_query = $transactionTypesTable->find('all')->select(['id'])->where(['name' => $jsonData->type]);
+ if($transaction_type_query->count() != 1) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'transaction type not found', 'details' => 'transaction type name: ' . $jsonData->type]);
+ }
+ $stateError->transaction_type_id = $transaction_type_query->first()->id;
+ $stateError->created = $jsonData->created;
+ $stateError->message_json = json_encode(['task_id' => $jsonData->id, 'error' => $jsonData->error, 'errorMessage' => $jsonData->errorMessage]);
+ if(!$stateErrorTable->save($stateError)) {
+ $this->returnJsonSaveError($stateError, [
+ 'state' => 'error',
+ 'msg' => 'error saving state_error in db',
+ 'details' => json_encode($stateError->getErrors())
+ ]);
+ }
+ return $this->returnJson(['state' => 'success']);
}
private function putTransaction($transactionBase64) {
diff --git a/community_server/src/Controller/PagesController.php b/community_server/src/Controller/PagesController.php
index 94508ad8b..69f57356b 100644
--- a/community_server/src/Controller/PagesController.php
+++ b/community_server/src/Controller/PagesController.php
@@ -46,6 +46,7 @@ class PagesController extends AppController
*/
public function display(...$path)
{
+
$count = count($path);
if (!$count) {
return $this->redirect('/');
@@ -61,6 +62,16 @@ class PagesController extends AppController
if (!empty($path[1])) {
$subpage = $path[1];
}
+ /*$session = $this->getRequest()->getSession();
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $result;
+ }
+ $user = $session->read('StateUser');
+ $login_server_session = $this->request->getCookie('GRADIDO_LOGIN', '');*/
+ if($page == "vue" || $page == "vue-dev") {
+ $this->viewBuilder()->setLayout(false);
+ }
$this->set(compact('page', 'subpage'));
try {
diff --git a/community_server/src/Controller/RolesController.php b/community_server/src/Controller/RolesController.php
new file mode 100644
index 000000000..80aa493d3
--- /dev/null
+++ b/community_server/src/Controller/RolesController.php
@@ -0,0 +1,108 @@
+paginate($this->Roles);
+
+ $this->set(compact('roles'));
+ }
+
+ /**
+ * View method
+ *
+ * @param string|null $id Role id.
+ * @return \Cake\Http\Response|null
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
+ */
+ public function view($id = null)
+ {
+ $role = $this->Roles->get($id, [
+ 'contain' => [],
+ ]);
+
+ $this->set('role', $role);
+ }
+
+ /**
+ * Add method
+ *
+ * @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
+ */
+ public function add()
+ {
+ $role = $this->Roles->newEntity();
+ if ($this->request->is('post')) {
+ $role = $this->Roles->patchEntity($role, $this->request->getData());
+ if ($this->Roles->save($role)) {
+ $this->Flash->success(__('The role has been saved.'));
+
+ return $this->redirect(['action' => 'index']);
+ }
+ $this->Flash->error(__('The role could not be saved. Please, try again.'));
+ }
+ $this->set(compact('role'));
+ }
+
+ /**
+ * Edit method
+ *
+ * @param string|null $id Role id.
+ * @return \Cake\Http\Response|null Redirects on successful edit, renders view otherwise.
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
+ */
+ public function edit($id = null)
+ {
+ $role = $this->Roles->get($id, [
+ 'contain' => [],
+ ]);
+ if ($this->request->is(['patch', 'post', 'put'])) {
+ $role = $this->Roles->patchEntity($role, $this->request->getData());
+ if ($this->Roles->save($role)) {
+ $this->Flash->success(__('The role has been saved.'));
+
+ return $this->redirect(['action' => 'index']);
+ }
+ $this->Flash->error(__('The role could not be saved. Please, try again.'));
+ }
+ $this->set(compact('role'));
+ }
+
+ /**
+ * Delete method
+ *
+ * @param string|null $id Role id.
+ * @return \Cake\Http\Response|null Redirects to index.
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
+ */
+ public function delete($id = null)
+ {
+ $this->request->allowMethod(['post', 'delete']);
+ $role = $this->Roles->get($id);
+ if ($this->Roles->delete($role)) {
+ $this->Flash->success(__('The role has been deleted.'));
+ } else {
+ $this->Flash->error(__('The role could not be deleted. Please, try again.'));
+ }
+
+ return $this->redirect(['action' => 'index']);
+ }
+}
diff --git a/community_server/src/Controller/StateBalancesController.php b/community_server/src/Controller/StateBalancesController.php
index ce5b2cac8..c89dce8db 100644
--- a/community_server/src/Controller/StateBalancesController.php
+++ b/community_server/src/Controller/StateBalancesController.php
@@ -2,11 +2,14 @@
namespace App\Controller;
use Cake\ORM\TableRegistry;
-use App\Controller\AppController;
+use Cake\I18n\Time;
use Model\Navigation\NaviHierarchy;
use Model\Navigation\NaviHierarchyEntry;
+use App\Controller\AppController;
+
+
/**
* StateBalances Controller
*
@@ -21,7 +24,7 @@ class StateBalancesController extends AppController
{
parent::initialize();
//$this->Auth->allow(['add', 'edit']);
- $this->Auth->allow(['overview', 'overviewGdt', 'ajaxGetBalance', 'ajaxListTransactions']);
+ $this->Auth->allow(['overview', 'overviewGdt', 'ajaxListTransactions', 'ajaxGdtOverview', 'ajaxGetBalance', 'ajaxGdtTransactions']);
$this->loadComponent('JsonRequestClient');
}
/**
@@ -38,8 +41,8 @@ class StateBalancesController extends AppController
$this->set(compact('stateBalances'));
}
-
- private function updateBalances($stateUserId)
+
+ private function updateBalance($stateUserId)
{
$stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions');
$transactionsTable = TableRegistry::getTableLocator()->get('Transactions');
@@ -51,7 +54,7 @@ class StateBalancesController extends AppController
->order(['transaction_id ASC'])
->contain(false);
- if(!$state_user_transactions) {
+ if(!$state_user_transactions || !$state_user_transactions->count()) {
//debug($state_user_transactions);
return true;
}
@@ -91,6 +94,28 @@ class StateBalancesController extends AppController
if(!$create_state_balance) {
$update_state_balance = true;
}
+ } else if(!$last_state_user_transaction) {
+
+ $creationsTable = TableRegistry::getTableLocator()->get('TransactionCreations');
+ $creationTransactions = $creationsTable
+ ->find('all')
+ ->where(['state_user_id' => $stateUserId])
+ ->contain(false);
+
+ $transferTable = TableRegistry::getTableLocator()->get('TransactionSendCoins');
+ $transferTransactions = $transferTable
+ ->find('all')
+ ->where(['OR' => ['state_user_id' => $stateUserId, 'receiver_user_id' => $stateUserId]])
+ ->contain(false);
+ if($creationTransactions->count() > 0 || $transferTransactions->count() > 0) {
+ $this->addAdminError(
+ 'StateBalances',
+ 'updateBalance', [
+ 'state' => 'error',
+ 'msg' => 'state_user_transactions is empty but it exist transactions for user'
+ ],
+ $stateUserId);
+ }
}
}
// second: do what is needed
@@ -176,6 +201,7 @@ class StateBalancesController extends AppController
}
}
return true;
+
}
public function overview()
@@ -195,7 +221,10 @@ class StateBalancesController extends AppController
}
$user = $session->read('StateUser');
- $this->updateBalances($user['id']);
+ $update_balance_result = $this->updateBalance($user['id']);
+ if($update_balance_result !== true) {
+ $this->addAdminError('StateBalances', 'overview', $update_balance_result, $user['id']);
+ }
// sendRequestGDT
// listPerEmailApi
@@ -215,6 +244,7 @@ class StateBalancesController extends AppController
//}
//
//
+ $stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions');
$creationsTable = TableRegistry::getTableLocator()->get('TransactionCreations');
$creationTransactions = $creationsTable
@@ -283,17 +313,22 @@ class StateBalancesController extends AppController
foreach ($transferTransactions as $sendCoins) {
$type = '';
$otherUser = null;
+ $other_user_public = '';
if ($sendCoins->state_user_id == $user['id']) {
$type = 'send';
if(isset($involvedUserIndices[$sendCoins->receiver_user_id])) {
$otherUser = $involvedUserIndices[$sendCoins->receiver_user_id];
}
+ $other_user_public = bin2hex(stream_get_contents($sendCoins->receiver_public_key));
} else if ($sendCoins->receiver_user_id == $user['id']) {
$type = 'receive';
if(isset($involvedUserIndices[$sendCoins->state_user_id])) {
$otherUser = $involvedUserIndices[$sendCoins->state_user_id];
}
+ if($sendCoins->sender_public_key) {
+ $other_user_public = bin2hex(stream_get_contents($sendCoins->sender_public_key));
+ }
}
if(null == $otherUser) {
$otherUser = $this->StateBalances->StateUsers->newEntity();
@@ -305,17 +340,101 @@ class StateBalancesController extends AppController
'transaction_id' => $sendCoins->transaction_id,
'date' => $sendCoins->transaction->received,
'balance' => $sendCoins->amount,
- 'memo' => $sendCoins->transaction->memo
+ 'memo' => $sendCoins->transaction->memo,
+ 'pubkey' => $other_user_public
]);
}
uasort($transactions, array($this, 'sortTransactions'));
- $this->set('transactions', $transactions);
+
+ // add decay transactions
+ $month_start_state_balance = null;
+ $current_state_balance = null;
+ $cursor = 0;
+ $transactions_reversed = array_reverse($transactions);
+ $maxI = count($transactions_reversed);
+ foreach($transactions_reversed as $i => $transaction) {
+ if(!isset($transaction['transaction_id'])) {
+ continue;
+ }
+ $transaction_id = $transaction['transaction_id'];
+ $decay_transaction = NULL;
+ $state_balance = $this->StateBalances->newEntity();
+
+ if($i > 0 && isset($transactions_reversed[$i-1]['transaction_id'])) {
+ $prev_transaction = $transactions_reversed[$i-1];
+ $stateUserTransactions = $stateUserTransactionsTable
+ ->find()
+ ->where([
+ 'transaction_id IN' => [$transaction_id, $prev_transaction['transaction_id']],
+ 'state_user_id' => $user['id']
+ ])
+ ->order(['transaction_id ASC'])
+ ->toArray();
+
+ $prev = $stateUserTransactions[0];
+ if($prev->balance > 0) {
+ // var_dump($stateUserTransactions);
+ $current = $stateUserTransactions[1];
+ $interval = $current->balance_date->diff($prev->balance_date);
+ $state_balance->amount = $prev->balance;
+ $state_balance->record_date = $prev->balance_date;
+ $diff_amount = $state_balance->partDecay($current->balance_date);
+ /* echo "prev date: $prev->balance_date, current date: $current->balance_date, interval: ";
+ var_dump($interval);
+ echo "
";
+ echo "prev balance: $prev->balance
diff: $diff_amount
";
+ echo "current balance: $current->balance
";
+ *
+ */
+ //echo $interval->format('%R%a days');
+ $decay_transaction = [
+ 'type' => 'decay',
+ 'balance' => -($prev->balance - $diff_amount),
+ 'decay_duration' => $interval->format('%a days, %H hours, %I minutes, %S seconds'),
+ 'memo' => ''
+ ];
+ }
+ }
+
+ if($decay_transaction) {
+ array_splice($transactions_reversed, $i + $cursor, 0, [$decay_transaction]);
+ $cursor++;
+ }
+ if($i == $maxI-1) {
+ $stateUserTransaction = $stateUserTransactionsTable
+ ->find()
+ ->where(['transaction_id' => $transaction_id, 'state_user_id' => $user['id']])
+ ->order(['transaction_id ASC'])->first();
+ //var_dump($stateUserTransaction);
+ $state_balance->amount = $stateUserTransaction->balance;
+ $state_balance->record_date = $stateUserTransaction->balance_date;
+ $transactions_reversed[] = [
+ 'type' => 'decay',
+ 'balance' => -($stateUserTransaction->balance - $state_balance->decay),
+ 'decay_duration' => $stateUserTransaction->balance_date->timeAgoInWords(),
+ 'memo' => ''
+ ];
+
+ }
+ }
+ // for debugging
+ $calculated_balance = 0;
+ foreach($transactions_reversed as $tr) {
+ if($tr['type'] == 'send') {
+ $calculated_balance -= intval($tr['balance']);
+ } else {
+ $calculated_balance += intval($tr['balance']);
+ }
+ }
+ $this->set('calculated_balance', $calculated_balance);
+
+ $this->set('transactions', array_reverse($transactions_reversed));
$this->set('transactionExecutingCount', $session->read('Transactions.executing'));
$this->set('balance', $session->read('StateUser.balance'));
$this->set('timeUsed', microtime(true) - $startTime);
$this->set('gdtSum', $gdtSum);
}
-
+
public function ajaxGetBalance($session_id = 0)
{
if(!$session_id) {
@@ -357,8 +476,9 @@ class StateBalancesController extends AppController
return $this->returnJson(['state' => 'success', 'balance' => $state_balances[0]->amount]);
}
-
- public function ajaxListTransactions($session_id = 0, $sort = 'ASC')
+
+
+ public function ajaxListTransactions($session_id, $page, $count)
{
if(!$session_id) {
return $this->returnJson(['state' => 'error', 'msg' => 'invalid session id']);
@@ -491,6 +611,42 @@ class StateBalancesController extends AppController
]);
}
+
+
+ public function ajaxGdtOverview()
+ {
+ $gdtSum = 0;
+ $gdtCount = -1;
+ $session = $this->getRequest()->getSession();
+ $user = $session->read('StateUser');
+
+ if(!$user) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'user not found', 'details' => 'exist a valid session cookie?']);
+ }
+ $gdtEntries = $this->JsonRequestClient->sendRequestGDT(['email' => $user['email']], 'GdtEntries' . DS . 'sumPerEmailApi');
+
+ if('success' == $gdtEntries['state'] && 'success' == $gdtEntries['data']['state']) {
+ $gdtSum = intval($gdtEntries['data']['sum']);
+ if(isset($gdtEntries['data']['count'])) {
+ $gdtCount = intval($gdtEntries['data']['count']);
+ }
+ } else {
+ if($user) {
+ $this->addAdminError('StateBalancesController', 'ajaxGdtOverview', $gdtEntries, $user['id']);
+ } else {
+ $this->addAdminError('StateBalancesController', 'ajaxGdtOverview', $gdtEntries, 0);
+ }
+ }
+
+ return $this->returnJson([
+ 'state' => 'success',
+ 'transactions' => $transactions,
+ 'transactionExecutingCount' => $session->read('Transaction.executing'),
+ 'count' => $all_user_transactions_count
+ ]);
+ }
+
+
public function overviewGdt()
{
$this->set(
@@ -536,9 +692,9 @@ class StateBalancesController extends AppController
//echo "gdtSum: $gdtSum
";
$this->set('gdtSum', $gdtSum);
$this->set('ownEntries', $ownEntries);
- $this->set('gdtSumPerEmail', $requestResult['data']['gdtSumPerEmail']);
- $this->set('moreEntrysAsShown', $requestResult['data']['moreEntrysAsShown']);
- $this->set('user', $user);
+ $this->set('gdtSumPerEmail', $requestResult['data']['gdtSumPerEmail']);
+ $this->set('moreEntrysAsShown', $requestResult['data']['moreEntrysAsShown']);
+ $this->set('user', $user);
if (isset($requestResult['data']['publishers'])) {
$publishers = $requestResult['data']['publishers'];
@@ -549,6 +705,66 @@ class StateBalancesController extends AppController
$this->Flash->error(__('Fehler beim GDT Server, bitte abwarten oder den Admin benachrichtigen!'));
}
}
+
+ public function ajaxGdtTransactions()
+ {
+ $startTime = microtime(true);
+ $session = $this->getRequest()->getSession();
+ $user = $session->read('StateUser');
+ if(!$user) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'user not found', 'details' => 'exist a valid session cookie?']);
+ }
+
+ $requestResult = $this->JsonRequestClient->sendRequestGDT(['email' => $user['email']], 'GdtEntries' . DS . 'listPerEmailApi');
+ $connectEntries = [];
+ $publishers = [];
+
+ //var_dump($requestResult);
+ if('success' === $requestResult['state'] && 'success' === $requestResult['data']['state']) {
+
+ //var_dump(array_keys($requestResult['data']));
+ $ownEntries = $requestResult['data']['ownEntries'];
+ //$gdtEntries = $requestResult['data']['entries'];
+
+ $gdtSum = 0;
+ foreach ($ownEntries as $i => $gdtEntry) {
+ $gdtSum += $gdtEntry['gdt'];
+ //echo "index: $i
";
+ //var_dump($gdtEntry);
+ }
+ if (isset($requestResult['data']['connectEntrys'])) {
+ $connectEntries = $requestResult['data']['connectEntrys'];
+
+ foreach ($connectEntries as $entry) {
+ //if(!$count) var_dump($entry);
+ //$count++;
+ $gdtSum += $entry['connect']['gdt_entry']['gdt'];
+ }
+ }
+
+ //echo "gdtSum: $gdtSum
";
+
+ if (isset($requestResult['data']['publishers'])) {
+ $publishers = $requestResult['data']['publishers'];
+ }
+ } else {
+ $this->addAdminError('StateBalancesController', 'ajaxGdtTransactions', $requestResult, $user['id']);
+ //$this->Flash->error(__('Fehler beim GDT Server, bitte abwarten oder den Admin benachrichtigen!'));
+ return $this->returnJson(['state' => 'error', 'msg' => 'error from gdt server', 'details' => $requestResult]);
+ }
+
+
+ return $this->returnJson([
+ 'state' => 'success',
+ 'gdtSum' => $gdtSum,
+ 'ownEntries' => $ownEntries,
+ 'connectEntries' => $connectEntries,
+ 'publishers' => $publishers,
+ 'gdtSumPerEmail' => $requestResult['data']['gdtSumPerEmail'],
+ 'moreEntrysAsShown' => $requestResult['data']['moreEntrysAsShown'],
+ 'timeUsed' => microtime(true) - $startTime
+ ]);
+ }
public function sortTransactions($a, $b)
{
diff --git a/community_server/src/Controller/StateGroupAddressesController.php b/community_server/src/Controller/StateGroupAddressesController.php
index 13f2b1f78..25afc82c7 100644
--- a/community_server/src/Controller/StateGroupAddressesController.php
+++ b/community_server/src/Controller/StateGroupAddressesController.php
@@ -20,7 +20,7 @@ class StateGroupAddressesController extends AppController
public function index()
{
$this->paginate = [
- 'contain' => ['StateGroups', 'AddressTypes']
+ 'contain' => ['AddressTypes'],
];
$stateGroupAddresses = $this->paginate($this->StateGroupAddresses);
@@ -37,7 +37,7 @@ class StateGroupAddressesController extends AppController
public function view($id = null)
{
$stateGroupAddress = $this->StateGroupAddresses->get($id, [
- 'contain' => ['StateGroups', 'AddressTypes']
+ 'contain' => ['StateGroups', 'AddressTypes'],
]);
$this->set('stateGroupAddress', $stateGroupAddress);
@@ -75,7 +75,7 @@ class StateGroupAddressesController extends AppController
public function edit($id = null)
{
$stateGroupAddress = $this->StateGroupAddresses->get($id, [
- 'contain' => []
+ 'contain' => [],
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$stateGroupAddress = $this->StateGroupAddresses->patchEntity($stateGroupAddress, $this->request->getData());
diff --git a/community_server/src/Controller/StateUserRolesController.php b/community_server/src/Controller/StateUserRolesController.php
new file mode 100644
index 000000000..9238c7ad6
--- /dev/null
+++ b/community_server/src/Controller/StateUserRolesController.php
@@ -0,0 +1,185 @@
+loadComponent('JsonRequestClient');
+ $this->Auth->allow([
+// 'search'
+ ]);
+ $this->set(
+ 'naviHierarchy',
+ (new NaviHierarchy())->
+ add(new NaviHierarchyEntry(__('Startseite'), 'Dashboard', 'index', false))->add(new NaviHierarchyEntry(__('Benutzer suchen'), 'StateUsers', 'search', true))
+ );
+ }
+
+ public function search()
+ {
+ $this->loadModel('StateUsers');
+ $startTime = microtime(true);
+ I18n::setLocale('de_DE');
+ $this->viewBuilder()->setLayout('frontend');
+
+ $searchForm = new UserSearchForm();
+
+ $timeUsed = microtime(true) - $startTime;
+ //$this->set('timeUsed', $timeUsed);
+ $this->set(compact('timeUsed', 'searchForm'));
+
+ if ($this->request->is('post')) {
+ $requestData = $this->request->getData();
+
+ if ($searchForm->validate($requestData)) {
+ //var_dump($requestData);
+ $searchString = $requestData['search'];
+
+ // find user on community server db
+ $globalSearch = '%' . $searchString . '%';
+ $communityUsers = $this->StateUsers
+ ->find('all')
+ ->contain([]);
+
+ $communityUsers->where(['OR' => [
+ 'first_name LIKE' => $globalSearch,
+ 'last_name LIKE' => $globalSearch,
+ //'username LIKE' => $globalSearch,
+ 'email LIKE' => $globalSearch
+ ]]);
+
+ //var_dump($communityUsers->toArray());
+ $finalUserEntrys = [];
+ // detect states
+ $this->loadModel('Roles');
+// foreach ($pubkeySorted as $pubhex => $user) {
+ foreach($communityUsers as $communityUser) {
+ $finalUser = $communityUser;
+ $finalUser['pubkeyhex'] = bin2hex(stream_get_contents($communityUser->public_key));
+
+ $state_user_id = $communityUser->id;
+ $stateUserRole = $this->StateUserRoles->find('all')->where(['state_user_id' => $state_user_id])->all();
+
+ $role_ids = "";
+ foreach ($stateUserRole as $userRole) {
+ if($role_ids != "")
+ $role_ids .= ",".$userRole->role_id;
+ else
+ $role_ids = $userRole->role_id;
+ }
+
+ $roles = $this->Roles->find('all')->where(['id IN' => explode(",",$role_ids)])->all();
+
+ $role_names = "";
+ foreach($roles as $role)
+ {
+ if($role_names != "")
+ $role_names .= "
".$role->title;
+ else
+ $role_names = $role->title;
+ }
+
+ $finalUser['role_name'] = $role_names;
+
+ array_push($finalUserEntrys, $finalUser);
+ }
+
+ //var_dump($pubkeySorted);
+ } else {
+ $this->Flash->error(__('Something was invalid, please try again!'));
+ }
+ $this->set('finalUserEntrys', $finalUserEntrys);
+ }
+ $timeUsed = microtime(true) - $startTime;
+ $this->set('timeUsed', $timeUsed);
+ }
+
+ public function assignRole()
+ {
+ $this->loadModel('Roles');
+ $this->loadModel('StateUsers');
+
+ if ($this->request->is('post')) {
+ $requestData = $this->request->getData();
+
+ $public_hex = hex2bin($requestData['public_hex']);
+
+ $stateUser = $this->StateUsers->find('all')->where(['public_key' => $public_hex])->first();
+
+ foreach($requestData['role_id'] as $role_id)
+ {
+ $newStateUserRole = $this->StateUserRoles->newEntity();
+
+ $post_data = [];
+ $post_data['state_user_id'] = $stateUser->id;
+ $post_data['role_id'] = $role_id;
+ $this->StateUserRoles->patchEntity($newStateUserRole, $post_data);
+ $this->StateUserRoles->save($newStateUserRole);
+
+ }
+
+ $this->Flash->success(__('Role has been assigned to User.'));
+
+ return $this->redirect(['controller' => 'state-user-roles', 'action' => 'search']);
+
+ }
+
+ $assignRoleForm = new AssignRoleForm();
+
+ $public_hex = $this->request->getParam('pass')[0];
+
+ $publichex = hex2bin($public_hex);
+
+ $stateUser = $this->StateUsers->find('all')->where(['public_key' => $publichex])->first();
+
+ $stateUserRoles = $this->StateUserRoles->find('all')->where(['state_user_id' => $stateUser->id])->all();
+
+ $role_ids = "";
+ foreach ($stateUserRoles as $userRole) {
+ if($role_ids != "")
+ $role_ids .= ",".$userRole->role_id;
+ else
+ $role_ids = $userRole->role_id;
+ }
+
+ $role_ids = explode(",", $role_ids);
+
+ $roles = $this->Roles->find('list', array('fields' => array('id', 'title')));
+
+
+ $this->set('roles', $roles);
+ $this->set('stateUser', $stateUser);
+ $this->set('role_ids', $role_ids);
+ $this->set('assignRoleForm', $assignRoleForm);
+ $this->set('public_hex', $public_hex);
+ }
+
+}
diff --git a/community_server/src/Controller/StateUserTransactionsController.php b/community_server/src/Controller/StateUserTransactionsController.php
index b51dd350f..f816192f3 100644
--- a/community_server/src/Controller/StateUserTransactionsController.php
+++ b/community_server/src/Controller/StateUserTransactionsController.php
@@ -20,6 +20,7 @@ class StateUserTransactionsController extends AppController
$this->Auth->allow(['ajaxListTransactions']);
//$this->loadComponent('JsonRequestClient');
}
+
/**
* Index method
*
diff --git a/community_server/src/Controller/StateUsersController.php b/community_server/src/Controller/StateUsersController.php
index 43c6664c0..fc6ec8614 100644
--- a/community_server/src/Controller/StateUsersController.php
+++ b/community_server/src/Controller/StateUsersController.php
@@ -5,8 +5,8 @@ use Cake\Routing\Router;
use Cake\I18n\I18n;
use Cake\I18n\FrozenTime;
use Cake\ORM\TableRegistry;
-use Cake\Http\Client;
use Cake\Core\Configure;
+use Cake\Http\Client;
use App\Controller\AppController;
use App\Form\UserSearchForm;
@@ -42,10 +42,11 @@ class StateUsersController extends AppController
parent::initialize();
$this->loadComponent('GradidoNumber');
$this->loadComponent('JsonRequestClient');
+ $this->loadComponent('Cookie');
$this->Auth->allow([
'search', 'ajaxCopyLoginToCommunity', 'ajaxCopyCommunityToLogin',
'ajaxDelete', 'ajaxCountTransactions', 'ajaxVerificationEmailResend',
- 'ajaxGetUserEmailVerificationCode', 'ajaxGetCSFRToken'
+ 'ajaxGetUserEmailVerificationCode', 'ajaxGetCSFRToken', 'login'
]);
$this->set(
'naviHierarchy',
@@ -72,11 +73,39 @@ class StateUsersController extends AppController
/*public function listIdentHashes()
{
$stateUsers = $this->StateUsers->find('all')->toArray();
- foreach ($stateUsers as $i => $user) {
- $stateUsers[$i]->identHash = TransactionCreation::DRMakeStringHash($user->email);
+ foreach($stateUsers as $i => $user) {
+ $stateUsers[$i]->identHash = TransactionCreation::DRMakeStringHash($user->email);
}
$this->set('stateUsers', $stateUsers);
}*/
+
+ public function login($session_id)
+ {
+ if(isset($session_id) && intval($session_id) !== 0) {
+ $loginServer = Configure::read('LoginServer');
+ $http = new Client();
+
+ try {
+ $url = $loginServer['host'] . ':' . $loginServer['port'];
+
+ $response = $http->get($url . '/login', ['session_id' => $session_id]);
+ $json = $response->getJson();
+
+ if (isset($json) && count($json) > 0) {
+ if ($json['state'] === 'success') {
+ $this->Cookie->configKey('GRADIDO_LOGIN', 'encryption', false);
+ $this->Cookie->write('GRADIDO_LOGIN', $session_id);
+ return $this->redirect(['controller' => 'Dashboard', 'action' => 'index']);
+ }
+ }
+ } catch (\Exception $e) {
+ $msg = $e->getMessage();
+ $this->Flash->error(__('error http request: ') . $msg);
+ return $this->redirect(['controller' => 'Dashboard', 'action' => 'errorHttpRequest']);
+ }
+ }
+ throw new NotFoundException();
+ }
public function search()
{
@@ -85,12 +114,12 @@ class StateUsersController extends AppController
$this->viewBuilder()->setLayout('frontend');
$session = $this->getRequest()->getSession();
$result = $this->requestLogin();
- if ($result !== true) {
- return $result;
+ if($result !== true) {
+ return $result;
}
$user = $session->read('StateUser');
- if ($user['role'] != 'admin') {
- return $this->redirect(['controller' => 'dashboard', 'action' => 'index']);
+ if($user['role'] != 'admin') {
+ return $this->redirect(['controller' => 'dashboard', 'action' => 'index']);
}
$searchForm = new UserSearchForm();
@@ -102,55 +131,55 @@ class StateUsersController extends AppController
$empty_string = '... empty ...';
if ($this->request->is('post')) {
$finalUserEntrys = [];
- $requestData = $this->request->getData();
+ $requestData = $this->request->getData();
$account_state = $requestData['account_state'];
if($requestData['search'] == '' && $account_state != 'all') {
$requestData['search'] = $empty_string;
}
- if ($searchForm->validate($requestData)) {
- //var_dump($requestData);
- $searchString = $requestData['search'];
- $searchType = 'unknown';
- if (GenericValidation::email($searchString, [])) {
- $searchType = 'email';
- }
- // find users on login server
+ if($searchForm->validate($requestData)) {
+ //var_dump($requestData);
+ $searchString = $requestData['search'];
+ $searchType = 'unknown';
+ if(GenericValidation::email($searchString, [])) {
+ $searchType = 'email';
+ }
+ // find users on login server
$resultJson = $this->JsonRequestClient->getUsers($session->read('session_id'), $searchString, $account_state);
- $loginServerUser = [];
- if ($resultJson['state'] == 'success') {
- $dataJson = $resultJson['data'];
- if ($dataJson['state'] != 'success') {
- if ($dataJson['msg'] == 'session not found') {
- $session->destroy();
- return $this->redirect(Router::url('/', true) . 'account', 303);
- }
- }
- //var_dump($dataJson);
- if (isset($dataJson['users'])) {
- $loginServerUser = $dataJson['users'];
- }
+ $loginServerUser = [];
+ if($resultJson['state'] == 'success') {
+ $dataJson = $resultJson['data'];
+ if($dataJson['state'] != 'success') {
+ if($dataJson['msg'] == 'session not found') {
+ $session->destroy();
+ return $this->redirect(Router::url('/', true) . 'account', 303);
+ }
+ }
+ //var_dump($dataJson);
+ if(isset($dataJson['users'])) {
+ $loginServerUser = $dataJson['users'];
+ }
+ }
+ $pubkeySorted = [];
+ $emptyPubkeys = [];
+ foreach($loginServerUser as $u) {
+ if(!isset($u['public_hex']) || $u['public_hex'] == '') {
+ array_push($emptyPubkeys, $u);
+ } else {
+ if(!isset($pubkeySorted[$u['public_hex']])) {
+ $pubkeySorted[$u['public_hex']] = ['login' => [], 'community' => []];
}
- $pubkeySorted = [];
- $emptyPubkeys = [];
- foreach ($loginServerUser as $u) {
- if (!isset($u['public_hex']) || $u['public_hex'] == '') {
- array_push($emptyPubkeys, $u);
- } else {
- if (!isset($pubkeySorted[$u['public_hex']])) {
- $pubkeySorted[$u['public_hex']] = ['login' => [], 'community' => []];
- }
- array_push($pubkeySorted[$u['public_hex']]['login'], $u);
- }
- }
- // find user on community server db
+ array_push($pubkeySorted[$u['public_hex']]['login'], $u);
+ }
+ }
+ // find user on community server db
- $communityUsers = $this->StateUsers
+ $communityUsers = $this->StateUsers
->find('all')
->contain(['StateBalances' => ['fields' => ['amount', 'state_user_id']]]);
-
+
if($account_state == 'email not activated') {
if(count($pubkeySorted) > 0) {
$communityUsers->where(['hex(public_key) IN' => array_keys($pubkeySorted)]);
@@ -159,112 +188,110 @@ class StateUsersController extends AppController
}
} else {
$globalSearch = '%' . $searchString . '%';
- $communityUsers->where(['OR' => [
- 'first_name LIKE' => $globalSearch,
- 'last_name LIKE' => $globalSearch,
- //'username LIKE' => $globalSearch,
- 'email LIKE' => $globalSearch
- ]]);
+ $communityUsers->where(['OR' => [
+ 'first_name LIKE' => $globalSearch,
+ 'last_name LIKE' => $globalSearch,
+ 'email LIKE' => $globalSearch
+ ]]);
}
- //var_dump($communityUsers->toArray());
+ //var_dump($communityUsers->toArray());
if($communityUsers) {
- foreach ($communityUsers as $u) {
- $pubkey_hex = bin2hex(stream_get_contents($u->public_key));
- $u->public_hex = $pubkey_hex;
- if (!isset($pubkeySorted[$pubkey_hex])) {
- $pubkeySorted[$pubkey_hex] = ['login' => [], 'community' => []];
- }
- array_push($pubkeySorted[$pubkey_hex]['community'], $u);
- }
+ foreach($communityUsers as $u) {
+ $pubkey_hex = bin2hex(stream_get_contents($u->public_key));
+ $u->public_hex = $pubkey_hex;
+ if(!isset($pubkeySorted[$pubkey_hex])) {
+ $pubkeySorted[$pubkey_hex] = ['login' => [], 'community' => []];
+ }
+ array_push($pubkeySorted[$pubkey_hex]['community'], $u);
+ }
}
- // detect states
- foreach ($pubkeySorted as $pubhex => $user) {
- $finalUser = [];
- $state = 'account created';
- $color = 'secondary';
- $finalUser['balance'] = 0;
- $finalUser['pubkeyhex'] = $pubhex;
- $finalUser['created'] = null;
+ // detect states
+ foreach($pubkeySorted as $pubhex => $user) {
+ $finalUser = [];
+ $state = 'account created';
+ $color = 'secondary';
+ $finalUser['balance'] = 0;
+ $finalUser['pubkeyhex'] = $pubhex;
+ $finalUser['created'] = null;
- if (count($user['community']) == 1) {
- if (isset($user['community'][0]->state_balances) &&
- isset($user['community'][0]->state_balances[0]['amount'])) {
- $finalUser['balance'] = $user['community'][0]->state_balances[0]->amount;
- }
- }
-
- if (count($user['login']) == 0) {
- $state = 'account not on login-server';
- $color = 'danger';
- if (count($user['community']) == 1) {
- $c_user = $user['community'][0];
- $finalUser['name'] = $c_user->first_name . ' ' . $c_user->last_name;
- $finalUser['first_name'] = $c_user->first_name;
- $finalUser['last_name'] = $c_user->last_name;
- //$finalUser['username'] = $c_user->username;
- $finalUser['email'] = $c_user->email;
- }
- } elseif (count($user['login']) == 1) {
- if ($user['login'][0]['email_checked'] == true) {
- $state = 'email activated';
- $color = 'primary';
-
- if (count($user['community']) == 1) {
- $state = 'account copied to community';
- $color = 'success';
- //var_dump($user['community'][0]->state_balances[0]['amount']);
- }
- } else {
- $state = 'email not activated';
- $color = 'warning';
- }
-
- $l_user = $user['login'][0];
- $finalUser['name'] = $l_user['first_name'] . ' ' . $l_user['last_name'];
- $finalUser['first_name'] = $l_user['first_name'];
- $finalUser['last_name'] = $l_user['last_name'];
- //$finalUser['username'] = $l_user['username'];
- $finalUser['email'] = $l_user['email'];
- $finalUser['created'] = new FrozenTime($l_user['created']);
- } else {
- $state = 'account multiple times on login-server';
- $color = 'danger';
- }
- $finalUser['indicator'] = ['name' => $state, 'color' => $color];
- array_push($finalUserEntrys, $finalUser);
+ if(count($user['community']) == 1) {
+ if(isset($user['community'][0]->state_balances) &&
+ isset($user['community'][0]->state_balances[0]['amount'])) {
+ $finalUser['balance'] = $user['community'][0]->state_balances[0]->amount;
}
+ }
- foreach ($emptyPubkeys as $user) {
- $finalUser = [];
- $state = 'account not on community server';
- $color = 'secondary';
- if ($user['email_checked'] == false) {
- $state = 'email not activated';
- $color = 'warning';
- } else {
- $state = 'no keys';
- $color = 'warning';
- }
- $finalUser['balance'] = 0;
- $finalUser['pubkeyhex'] = '';
- $finalUser['name'] = $user['first_name'] . ' ' . $user['last_name'];
- $finalUser['first_name'] = $user['first_name'];
- $finalUser['last_name'] = $user['last_name'];
- //$finalUser['username'] = $user['username'];
- $finalUser['email'] = $user['email'];
- $finalUser['created'] = new FrozenTime($user['created']);
- $finalUser['indicator'] = ['name' => $state, 'color' => $color];
- array_push($finalUserEntrys, $finalUser);
+ if(count($user['login']) == 0) {
+ $state = 'account not on login-server';
+ $color = 'danger';
+ if(count($user['community']) == 1) {
+ $c_user = $user['community'][0];
+ $finalUser['name'] = $c_user->first_name . ' ' . $c_user->last_name;
+ $finalUser['first_name'] = $c_user->first_name;
+ $finalUser['last_name'] = $c_user->last_name;
+ $finalUser['email'] = $c_user->email;
}
- //var_dump($pubkeySorted);
- } else {
- $this->Flash->error(__('Something was invalid, please try again!'));
+ } else if(count($user['login']) == 1) {
+ if($user['login'][0]['email_checked'] == true) {
+ $state = 'email activated';
+ $color = 'primary';
+
+ if(count($user['community']) == 1) {
+ $state = 'account copied to community';
+ $color = 'success';
+ //var_dump($user['community'][0]->state_balances[0]['amount']);
+ }
+
+ } else {
+ $state = 'email not activated';
+ $color = 'warning';
+ }
+
+ $l_user = $user['login'][0];
+ $finalUser['name'] = $l_user['first_name'] . ' ' . $l_user['last_name'];
+ $finalUser['first_name'] = $l_user['first_name'];
+ $finalUser['last_name'] = $l_user['last_name'];
+ $finalUser['email'] = $l_user['email'];
+ $finalUser['created'] = new FrozenTime($l_user['created']);
+
+ } else {
+ $state = 'account multiple times on login-server';
+ $color = 'danger';
+ }
+ $finalUser['indicator'] = ['name' => $state, 'color' => $color];
+ array_push($finalUserEntrys, $finalUser);
}
- $this->set('finalUserEntrys', $finalUserEntrys);
+ foreach($emptyPubkeys as $user) {
+ $finalUser = [];
+ $state = 'account not on community server';
+ $color = 'secondary';
+ if($user['email_checked'] == false) {
+ $state = 'email not activated';
+ $color = 'warning';
+ } else {
+ $state = 'no keys';
+ $color = 'warning';
+ }
+ $finalUser['balance'] = 0;
+ $finalUser['pubkeyhex'] = '';
+ $finalUser['name'] = $user['first_name'] . ' ' . $user['last_name'];
+ $finalUser['first_name'] = $user['first_name'];
+ $finalUser['last_name'] = $user['last_name'];
+ $finalUser['email'] = $user['email'];
+ $finalUser['created'] = new FrozenTime($user['created']);
+ $finalUser['indicator'] = ['name' => $state, 'color' => $color];
+ array_push($finalUserEntrys, $finalUser);
+ }
+ //var_dump($pubkeySorted);
+ } else {
+ $this->Flash->error(__('Something was invalid, please try again!'));
+ }
+
+ $this->set('finalUserEntrys', $finalUserEntrys);
}
$timeUsed = microtime(true) - $startTime;
$this->set('timeUsed', $timeUsed);
@@ -272,187 +299,189 @@ class StateUsersController extends AppController
public function ajaxCopyCommunityToLogin()
{
- $session = $this->getRequest()->getSession();
- $result = $this->requestLogin();
- if ($result !== true) {
- return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
- }
- $user = $session->read('StateUser');
- if ($user['role'] != 'admin') {
- return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
- }
- if ($this->request->is('post')) {
- $jsonData = $this->request->input('json_decode', true);
- }
- return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
+ $session = $this->getRequest()->getSession();
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
+ }
+ $user = $session->read('StateUser');
+ if($user['role'] != 'admin') {
+ return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
+ }
+ if($this->request->is('post')) {
+ $jsonData = $this->request->input('json_decode', true);
+ }
+ return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
}
public function ajaxCopyLoginToCommunity()
{
- $session = $this->getRequest()->getSession();
- $result = $this->requestLogin();
- if ($result !== true) {
- return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
- }
- $user = $session->read('StateUser');
- if ($user['role'] != 'admin') {
- return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
- }
+ $session = $this->getRequest()->getSession();
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
+ }
+ $user = $session->read('StateUser');
+ if($user['role'] != 'admin') {
+ return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
+ }
- if ($this->request->is('post')) {
- $jsonData = $this->request->input('json_decode', true);
- //$user = $jsonData['user'];
- //var_dump($jsonData);
+ if($this->request->is('post')) {
+ $jsonData = $this->request->input('json_decode', true);
+ //$user = $jsonData['user'];
+ //var_dump($jsonData);
- $newStateUser = $this->StateUsers->newEntity();
- $this->StateUsers->patchEntity($newStateUser, $jsonData);
- $newStateUser->public_key = hex2bin($jsonData['pubkeyhex']);
+ $newStateUser = $this->StateUsers->newEntity();
+ $this->StateUsers->patchEntity($newStateUser, $jsonData);
+ $newStateUser->public_key = hex2bin($jsonData['pubkeyhex']);
- if (!$this->StateUsers->save($newStateUser)) {
- return $this->returnJson(['state' => 'error', 'msg' => 'error by saving', 'details' => json_encode($newStateUser->errors())]);
- }
+ if(!$this->StateUsers->save($newStateUser)) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'error by saving', 'details' => json_encode($newStateUser->errors())]);
+ }
- return $this->returnJson(['state' => 'success']);
- }
- return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
+ return $this->returnJson(['state' => 'success']);
+ }
+ return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
}
public function ajaxVerificationEmailResend()
{
- $session = $this->getRequest()->getSession();
- $result = $this->requestLogin();
- if ($result !== true) {
- return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
- }
- $user = $session->read('StateUser');
- if ($user['role'] != 'admin') {
- return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
- }
- if ($this->request->is('post')) {
- $jsonData = $this->request->input('json_decode', true);
- $email = $jsonData['email'];
- $session_id = $session->read('session_id');
+ $session = $this->getRequest()->getSession();
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
+ }
+ $user = $session->read('StateUser');
+ if($user['role'] != 'admin') {
+ return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
+ }
+ if($this->request->is('post')) {
+ $jsonData = $this->request->input('json_decode', true);
+ $email = $jsonData['email'];
+ $session_id = $session->read('session_id');
- return $this->returnJson($this->JsonRequestClient->sendRequest(json_encode([
+ return $this->returnJson($this->JsonRequestClient->sendRequest(json_encode([
'session_id' => $session_id,
'email' => $email
- ]), '/adminEmailVerificationResend'));
- /*return $this->sendRequest(json_encode([
+ ]), '/adminEmailVerificationResend'));
+ /*return $this->sendRequest(json_encode([
'session_id' => $session_id,
'search' => $searchString
- ]), '/getUsers');*/
- }
- return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
+ ]), '/getUsers');*/
+ }
+ return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
}
public function ajaxGetUserEmailVerificationCode()
{
- $session = $this->getRequest()->getSession();
- $result = $this->requestLogin();
- if ($result !== true) {
- return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
- }
- $user = $session->read('StateUser');
- if ($user['role'] != 'admin') {
- return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
- }
- if ($this->request->is('post')) {
- $jsonData = $this->request->input('json_decode', true);
- $email = $jsonData['email'];
- $session_id = $session->read('session_id');
+ $session = $this->getRequest()->getSession();
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
+ }
+ $user = $session->read('StateUser');
+ if($user['role'] != 'admin') {
+ return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
+ }
+ if($this->request->is('post')) {
+ $jsonData = $this->request->input('json_decode', true);
+ $email = $jsonData['email'];
+ $session_id = $session->read('session_id');
- return $this->returnJson($this->JsonRequestClient->sendRequest(json_encode([
+ return $this->returnJson($this->JsonRequestClient->sendRequest(json_encode([
'session_id' => $session_id,
'email' => $email,
'ask' => ['EmailVerificationCode.Register', 'loginServer.path']
- ]), '/getUserInfos'));
- }
- return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
+ ]), '/getUserInfos'));
+ }
+ return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
}
public function ajaxDelete()
{
- $session = $this->getRequest()->getSession();
- $result = $this->requestLogin();
- if ($result !== true) {
- return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
- }
- $user = $session->read('StateUser');
- if ($user['role'] != 'admin') {
- return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
- }
+ $session = $this->getRequest()->getSession();
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
+ }
+ $user = $session->read('StateUser');
+ if($user['role'] != 'admin') {
+ return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
+ }
- if ($this->request->is('post')) {
- $jsonData = $this->request->input('json_decode', true);
- //$user = $jsonData['user'];
- //var_dump($jsonData);
- $pubkey = hex2bin($jsonData['pubkeyhex']);
- $stateUsers = $this->StateUsers->find('all')->where(['public_key' => $pubkey]);
- if ($stateUsers->count() != 1) {
- return $this->returnJson(['state' => 'error', 'msg' => 'invalid result count']);
- }
+ if($this->request->is('post')) {
+ $jsonData = $this->request->input('json_decode', true);
+ //$user = $jsonData['user'];
+ //var_dump($jsonData);
+ $pubkey = hex2bin($jsonData['pubkeyhex']);
+ $stateUsers = $this->StateUsers->find('all')->where(['public_key' => $pubkey]);
+ if($stateUsers->count() != 1) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'invalid result count']);
+ }
- if ($this->StateUsers->delete($stateUsers->first())) {
- return $this->returnJson(['state' => 'success']);
- } else {
- return $this->returnJson(['state' => 'error', 'msg' => 'error by deleting', 'details' => json_encode($stateUser->errors())]);
- }
- }
- return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
+ if ($this->StateUsers->delete($stateUsers->first())) {
+ return $this->returnJson(['state' => 'success']);
+ } else {
+ return $this->returnJson(['state' => 'error', 'msg' => 'error by deleting', 'details' => json_encode($stateUser->errors())]);
+ }
+ }
+ return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
}
public function ajaxCountTransactions()
{
- $session = $this->getRequest()->getSession();
- $result = $this->requestLogin();
- if ($result !== true) {
- return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
- }
- $user = $session->read('StateUser');
- if ($user['role'] != 'admin') {
- return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
- }
+ $session = $this->getRequest()->getSession();
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
+ }
+ $user = $session->read('StateUser');
+ if($user['role'] != 'admin') {
+ return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
+ }
- if ($this->request->is('post')) {
- $jsonData = $this->request->input('json_decode', true);
- //$user = $jsonData['user'];
- //var_dump($jsonData);
- $pubkey = hex2bin($jsonData['pubkeyhex']);
- $stateUsers = $this->StateUsers
+ if($this->request->is('post')) {
+ $jsonData = $this->request->input('json_decode', true);
+ //$user = $jsonData['user'];
+ //var_dump($jsonData);
+ $pubkey = hex2bin($jsonData['pubkeyhex']);
+ $stateUsers = $this->StateUsers
->find('all')
->where(['public_key' => $pubkey])
->select(['id']);
- if ($stateUsers->count() != 1) {
- return $this->returnJson(['state' => 'error', 'msg' => 'invalid result count']);
- }
- $stateUser = $stateUsers->first();
- //var_dump($stateUser);
- //var_dump($stateUser->toArray());
- $creationsTable = TableRegistry::getTableLocator()->get('TransactionCreations');
- $creationTransactions = $creationsTable
+ if($stateUsers->count() != 1) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'invalid result count']);
+ }
+ $stateUser = $stateUsers->first();
+ //var_dump($stateUser);
+ //var_dump($stateUser->toArray());
+ $creationsTable = TableRegistry::getTableLocator()->get('TransactionCreations');
+ $creationTransactions = $creationsTable
->find('all')
->select(['id'])
->where(['state_user_id' => $stateUser->id]);
- $transferTable = TableRegistry::getTableLocator()->get('TransactionSendCoins');
- $transferTransactions = $transferTable
+ $transferTable = TableRegistry::getTableLocator()->get('TransactionSendCoins');
+ $transferTransactions = $transferTable
->find('all')
->where(['OR' => ['state_user_id' => $stateUser->id, 'receiver_user_id' => $stateUser->id]])
->select(['state_user_id', 'receiver_user_id']);
- $counts = ['creation' => $creationTransactions->count(), 'receive' => 0, 'sended' => 0];
- foreach ($transferTransactions as $transfer) {
- //var_dump($transfer);
- if ($transfer->state_user_id == $stateUser->id) {
- $counts['sended']++;
- }
- if ($transfer->receiver_user_id == $stateUser->id) {
- $counts['receive']++;
- }
+ $counts = ['creation' => $creationTransactions->count(), 'receive' => 0, 'sended' => 0];
+ foreach($transferTransactions as $transfer) {
+ //var_dump($transfer);
+ if($transfer->state_user_id == $stateUser->id) {
+ $counts['sended']++;
}
- return $this->returnJson(['state' => 'success', 'counts' => $counts]);
- }
- return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
+ if($transfer->receiver_user_id == $stateUser->id) {
+ $counts['receive']++;
+ }
+ }
+ return $this->returnJson(['state' => 'success', 'counts' => $counts]);
+
+ }
+ return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
+
}
public function ajaxGetCSFRToken($session_id)
@@ -560,9 +589,9 @@ class StateUsersController extends AppController
}
$this->Flash->error(__('The state user could not be saved. Please, try again.'));
}
-
+ $indices = $this->StateUsers->Indices->find('list', ['limit' => 200]);
$stateGroups = $this->StateUsers->StateGroups->find('list', ['limit' => 200]);
- $this->set(compact('stateUser', 'stateGroups'));
+ $this->set(compact('stateUser', 'indices', 'stateGroups'));
}
/**
diff --git a/community_server/src/Controller/TransactionCreationsController.php b/community_server/src/Controller/TransactionCreationsController.php
index 46a7a37f4..d02320d25 100644
--- a/community_server/src/Controller/TransactionCreationsController.php
+++ b/community_server/src/Controller/TransactionCreationsController.php
@@ -130,8 +130,7 @@ class TransactionCreationsController extends AppController
$builderResult = TransactionCreation::build(
$amountCent,
$requestData['memo'],
- $pubKeyHex,
- $identHash
+ $pubKeyHex
);
if ($builderResult['state'] == 'success') {
$user_balance = 0;
@@ -335,6 +334,7 @@ class TransactionCreationsController extends AppController
if (isset($requestData['add'])) {
$mode = 'add';
}
+ //echo "mode: $mode
";
$memo = $requestData['memo'];
$amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']);
//$targetDate = $requestData['target_date'];
@@ -342,17 +342,20 @@ class TransactionCreationsController extends AppController
$this->Flash->error(__('No user selected'));
} else {
$users = $requestData['user'];
+ $pendingTransactionCount = $session->read('Transactions.pending');
+ if ($pendingTransactionCount == null) {
+ $pendingTransactionCount = 0;
+ }
if (isset($requestData['user_pending'])) {
$pendings = $requestData['user_pending'];
} else {
$pendings = [];
}
- $receiverUsers = $stateUserTable
- ->find('all')
- ->where(['id IN' => array_keys($users)])
- ->select(['public_key', 'email', 'id'])
- ->contain(false);
- $transactions = [];
+ $receiverUsers = $stateUserTable->find('all')
+ ->where(['id IN' => array_keys($users)])
+ ->select(['public_key', 'email', 'id'])
+ ->contain(false);
+
foreach ($receiverUsers as $receiverUser) {
$localAmountCent = $amountCent;
//$localTargetDate = $targetDate;
@@ -385,22 +388,85 @@ class TransactionCreationsController extends AppController
//$identHash = TransactionCreation::DRMakeStringHash($receiverUser->email);
$localTargetDateFrozen = FrozenDate::now();
$localTargetDateFrozen = $localTargetDateFrozen
- ->year($localTargetDate['year'])
- ->month($localTargetDate['month'])
- ->day($localTargetDate['day']);
- //echo "input: "; var_dump($localTargetDate);echo "
";
- //echo "output: "; var_dump($localTargetDateFrozen);
- //die('a');
- $builderResult = TransactionCreation::build(
- $localAmountCent,
- $memo,
- $pubKeyHex,
- $identHash,
- $localTargetDateFrozen
- );
- if ($builderResult['state'] == 'success') {
- array_push($transactions, base64_encode($builderResult['transactionBody']->serializeToString()));
+ ->year($localTargetDate['year'])
+ ->month($localTargetDate['month'])
+ ->day($localTargetDate['day']);
+
+ $requestAnswear = $this->JsonRequestClient->sendRequest(json_encode([
+ 'session_id' => $session->read('session_id'),
+ 'transaction_type' => 'creation',
+ 'memo' => $memo,
+ 'amount' => $localAmountCent,
+ 'target_pubkey' => $pubKeyHex,
+ 'target_date' => $localTargetDateFrozen,
+ 'blockchain_type' => $this->blockchainType
+ ]), '/createTransaction');
+
+ if('success' != $requestAnswear['state']) {
+ $this->addAdminError('TransactionCreations', 'createMulti', $requestAnswear, $user['id']);
+ if ($requestResult['type'] == 'request error') {
+ $this->Flash->error(__('Error by requesting LoginServer, please try again'));
+ } else {
+ $this->Flash->error(__('Error, please wait for the admin to fix it'));
+ }
}
+ if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) {
+ $pendingTransactionCount++;
+ //echo "pending transaction count: $pendingTransactionCount
";
+ } else {
+ /*
+ * if request contain unknown parameter format, shouldn't happen't at all
+ * {"state": "error", "msg": "parameter format unknown"}
+ * if json parsing failed
+ * {"state": "error", "msg": "json exception", "details":"exception text"}
+ * if session_id is zero or not set
+ * {"state": "error", "msg": "session_id invalid"}
+ * if session id wasn't found on login server, if server was restartet or user logged out (also per timeout, default: 15 minutes)
+ * {"state": "error", "msg": "session not found"}
+ * if session hasn't active user, shouldn't happen't at all, login-server should be checked if happen
+ * {"state": "code error", "msg":"user is zero"}
+ * if transaction type not known
+ * {"state": "error", "msg":"transaction_type unknown"}
+ * if receiver wasn't known to Login-Server
+ * {"state": "not found", "msg":"receiver not found"}
+ * if receiver account disabled, and therefor cannto receive any coins
+ * {"state": "disabled", "msg":"receiver is disabled"}
+ * if amount is invalid in creation
+ * {"state": "invalid parameter", "msg":"invalid amount", "details":"GDD amount in GDD cent ]0,10000000]"}
+ * if transaction was okay and will be further proccessed
+ * {"state":"success"}
+ */
+ $answear_data = $requestAnswear['data'];
+ if($answear_data['state'] === 'error') {
+ if($answear_data['msg'] === 'session_id invalid' || $answear_data['msg'] === 'session not found') {
+ $this->Flash->error(__('Fehler mit der Session, bitte logge dich erneut ein!'));
+ $this->set('timeUsed', microtime(true) - $startTime);
+ return;
+ }
+ if($answear_data['msg'] === 'user not in group') {
+ $this->Flash->error(__('Fehler, Benutzer gehört zu einer anderen Gruppe!'));
+ $this->set('timeUsed', microtime(true) - $startTime);
+ return;
+ }
+ } else if($answear_data['state'] === 'not found' && $answear_data['msg'] === 'receiver not found') {
+ $this->Flash->error(__('Der Empfänger wurde nicht auf dem Login-Server gefunden, hat er sein Konto schon angelegt?'));
+ $this->set('timeUsed', microtime(true) - $startTime);
+ return;
+ } else if($answear_data['state'] === 'disabled') {
+ $this->Flash->error(__('Der Empfänger ist deaktiviert, daher können ihm zurzeit keine Gradidos gesendet werden.'));
+ $this->set('timeUsed', microtime(true) - $startTime);
+ return;
+ } else if($answear_data['msg'] === 'invalid amount') {
+ $this->Flash->error(__('Der Betrag ist ungültig, er muss größer als 0 und <= 1000 sein.'));
+ $this->set('timeUsed', microtime(true) - $startTime);
+ return;
+ } else {
+ $this->Flash->error(__('Unbehandelter Fehler: ') . json_encode($answear_data));
+ $this->set('timeUsed', microtime(true) - $startTime);
+ return;
+ }
+ }
+
}
/*echo "pendings: ";
var_dump($pendings);
@@ -412,49 +478,17 @@ class TransactionCreationsController extends AppController
}
}
$this->set('possibleReceivers', $possibleReceivers);
- $creationTransactionCount = count($transactions);
- if ($creationTransactionCount > 0) {
+ if ($pendingTransactionCount > 0) {
$user_balance = 0;
if (isset($user['balance'])) {
$user_balance = $user['balance'];
}
- // $session_id, $base64Message, $user_balance = 0
- $requestResult = $this->JsonRequestClient->sendTransaction(
- $session->read('session_id'),
- $transactions,
- $user_balance
- );
- if ($requestResult['state'] != 'success') {
- $this->addAdminError('TransactionCreations', 'createMulti', $requestResult, $user['id']);
- if ($requestResult['type'] == 'request error') {
- $this->Flash->error(__('Error by requesting LoginServer, please try again'));
- } else {
- $this->Flash->error(__('Error, please wait for the admin to fix it'));
- }
+ $session->write('Transactions.pending', $pendingTransactionCount);
+
+ if ($mode === 'next') {
+ return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303);
} else {
- $json = $requestResult['data'];
- if ($json['state'] != 'success') {
- if ($json['msg'] == 'session not found') {
- $session->destroy();
- return $this->redirect($this->loginServerUrl . 'account', 303);
- } else {
- $this->addAdminError('TransactionCreations', 'createMulti', $json, $user['id']);
- $this->Flash->error(__('Login Server Error, please wait for the admin to fix it'));
- }
- } else {
- $pendingTransactionCount = $session->read('Transactions.pending');
- if ($pendingTransactionCount == null) {
- $pendingTransactionCount = $creationTransactionCount;
- } else {
- $pendingTransactionCount += $creationTransactionCount;
- }
- $session->write('Transactions.pending', $pendingTransactionCount);
- if ($mode === 'next') {
- return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303);
- } else {
- $this->Flash->success(__('Transaction submitted for review.'));
- }
- }
+ $this->Flash->success(__('Transaction submitted for review.'));
}
}
}
@@ -533,7 +567,6 @@ class TransactionCreationsController extends AppController
$amount,
$memo,
$receiverPubKeyHex,
- $requestAnswear['data']['userData']['identHash'],
new FrozenDate($jsonData['target_date'])
);
$transaction_base64 = '';
@@ -546,7 +579,8 @@ class TransactionCreationsController extends AppController
$session_id,
$transaction_base64,
$user['balance'],
- $auto_sign
+ $auto_sign,
+ $this->blockchainType
);
if ($requestResult['state'] != 'success') {
$msg = 'error returned from login server';
diff --git a/community_server/src/Controller/TransactionSendCoinsController.php b/community_server/src/Controller/TransactionSendCoinsController.php
index 2f48de063..033e2343f 100644
--- a/community_server/src/Controller/TransactionSendCoinsController.php
+++ b/community_server/src/Controller/TransactionSendCoinsController.php
@@ -57,8 +57,9 @@ class TransactionSendCoinsController extends AppController
'contain' => ['Transactions', 'StateUsers', 'ReceiverUsers']
];
$transactionSendCoins = $this->paginate($this->TransactionSendCoins);
+ $simple = $this->TransactionSendCoins->find('all');
- $this->set(compact('transactionSendCoins'));
+ $this->set(compact('transactionSendCoins', 'simple'));
}
/**
@@ -146,10 +147,17 @@ class TransactionSendCoinsController extends AppController
}
$user = $session->read('StateUser');
}
+
+ $known_groups = $this->JsonRequestClient->sendRequest(json_encode([
+ 'ask' => ['groups']
+ ]), '/networkInfos');
+
$transferForm = new TransferForm();
$this->set('transferForm', $transferForm);
$this->set('timeUsed', microtime(true) - $startTime);
+ $this->set('groups', $known_groups['data']['data']['groups']);
+ $this->set('user', $user);
if ($this->request->is('post')) {
//$this->Flash->error(__('Wird zurzeit noch entwickelt!'));
@@ -159,134 +167,94 @@ class TransactionSendCoinsController extends AppController
if(isset($requestData['add'])) {$mode = 'add'; }
if($transferForm->validate($requestData)) {
- $receiverPubKeyHex = '';
- $senderPubKeyHex = $user['public_hex'];
$amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']);
if(!isset($user['balance']) || $amountCent > $user['balance']) {
$this->Flash->error(__('Du hast nicht genug Geld!'));
return;
}
-
+
$receiverEmail = $requestData['email'];
if($receiverEmail === $user['email']) {
$this->Flash->error(__('Du kannst dir leider nicht selbst Geld schicken!'));
return;
}
- $receiverPubkeyHex ='';
$requestAnswear = $this->JsonRequestClient->sendRequest(json_encode([
'session_id' => $session->read('session_id'),
- 'email' => $receiverEmail,
- 'ask' => ['user.pubkeyhex', 'user.disabled']
- ]), '/getUserInfos');
+ 'transaction_type' => 'transfer',
+ 'memo' => $requestData['memo'],
+ 'amount' => $amountCent,
+ 'target_group' => $known_groups['data']['data']['groups'][$requestData['group']],
+ 'target_email' => $receiverEmail,
+ 'blockchain_type' => $this->blockchainType
+ ]), '/createTransaction');
+
if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) {
- // will be allways 64 byte long, even if it is empty
- $receiverPubKeyHex = $requestAnswear['data']['userData']['pubkeyhex'];
- } else {
- $this->addAdminError('TransactionSendCoins', 'create', $requestAnswear, $user['id']);
- $this->Flash->error(__('Der Empfänger wurde nicht auf dem Login-Server gefunden, hat er sein Konto schon angelegt?'));
- $this->set('timeUsed', microtime(true) - $startTime);
- return;
- }
- if($requestAnswear['data']['userData']['disabled']) {
- $this->Flash->error(__('Der Empfänger ist deaktiviert, daher können ihm zurzeit keine Gradidos gesendet werden.'));
- $this->set('timeUsed', microtime(true) - $startTime);
- return;
- }
-
-
- if(0 == ord($receiverPubKeyHex)) {
- $stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
- $receiverUser = $stateUserTable
- ->find('all')
- ->select(['public_key'])
- ->contain(false)
- ->where(['email' => $receiverEmail]);
-
-
- if(!$receiverUser) {
- $this->Flash->error(__('Diese E-Mail ist mir nicht bekannt, hat dein Empfänger denn schon ein Gradido-Konto?'));
- $this->set('timeUsed', microtime(true) - $startTime);
- return;
- }
-
- if(isset($receiverUser->public_key)) {
- $receiverPubKeyHex = bin2hex(stream_get_contents($receiverUser->public_key));
+ $pendingTransactionCount = $session->read('Transactions.pending');
+ if($pendingTransactionCount == null) {
+ $pendingTransactionCount = 1;
} else {
- $this->Flash->error(__('Das Konto mit der E-Mail: ' . $receiverEmail . ' wurde noch nicht aktiviert und kann noch keine GDD empfangen!'));
+ $pendingTransactionCount++;
+ }
+ $session->write('Transactions.pending', $pendingTransactionCount);
+ //echo "pending: " . $pendingTransactionCount;
+ if($mode === 'next') {
+ return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303);
+ } else {
+ $this->Flash->success(__('Transaction submitted for review.'));
+ }
+ } else {
+
+ /*
+ * if request contain unknown parameter format, shouldn't happen't at all
+ * {"state": "error", "msg": "parameter format unknown"}
+ * if json parsing failed
+ * {"state": "error", "msg": "json exception", "details":"exception text"}
+ * if session_id is zero or not set
+ * {"state": "error", "msg": "session_id invalid"}
+ * if session id wasn't found on login server, if server was restartet or user logged out (also per timeout, default: 15 minutes)
+ * {"state": "error", "msg": "session not found"}
+ * if session hasn't active user, shouldn't happen't at all, login-server should be checked if happen
+ * {"state": "code error", "msg":"user is zero"}
+ * if transaction type not known
+ * {"state": "error", "msg":"transaction_type unknown"}
+ * if receiver wasn't known to Login-Server
+ * {"state": "not found", "msg":"receiver not found"}
+ * if receiver account disabled, and therefor cannto receive any coins
+ * {"state": "disabled", "msg":"receiver is disabled"}
+ * if transaction was okay and will be further proccessed
+ * {"state":"success"}
+ */
+ $answear_data = $requestAnswear['data'];
+ if($answear_data['state'] === 'error') {
+ if($answear_data['msg'] === 'session_id invalid' || $answear_data['msg'] === 'session not found') {
+ $this->Flash->error(__('Fehler mit der Session, bitte logge dich erneut ein!'));
+ $this->set('timeUsed', microtime(true) - $startTime);
+ return;
+ }
+ if($answear_data['msg'] === 'user not in group') {
+ $this->Flash->error(__('Empfänger befindet sich nicht in Zielgruppe!'));
+ $this->set('timeUsed', microtime(true) - $startTime);
+ return;
+ }
+ } else if($answear_data['state'] === 'not found' && $answear_data['msg'] === 'receiver not found') {
+ $this->Flash->error(__('Der Empfänger wurde nicht auf dem Login-Server gefunden, hat er sein Konto schon angelegt?'));
$this->set('timeUsed', microtime(true) - $startTime);
return;
- }
+ } else if($answear_data['state'] === 'disabled') {
+ $this->Flash->error(__('Der Empfänger ist deaktiviert, daher können ihm zurzeit keine Gradidos gesendet werden.'));
+ $this->set('timeUsed', microtime(true) - $startTime);
+ return;
+ } else {
+ $this->Flash->error(__('Unbehandelter Fehler: ') . json_encode($answear_data));
+ $this->set('timeUsed', microtime(true) - $startTime);
+ return;
+ }
}
- //var_dump($sessionStateUser);
-
- $builderResult = TransactionTransfer::build(
- $amountCent,
- $requestData['memo'],
- $receiverPubKeyHex,
- $senderPubKeyHex
- );
- if($builderResult['state'] === 'success') {
-
- $http = new Client();
- try {
- $loginServer = Configure::read('LoginServer');
- $url = $loginServer['host'] . ':' . $loginServer['port'];
- $session_id = $session->read('session_id');
- /*
- *
- * $response = $http->post(
- * 'http://example.com/tasks',
- * json_encode($data),
- * ['type' => 'json']
- * );
- */
- $response = $http->post($url . '/checkTransaction', json_encode([
- 'session_id' => $session_id,
- 'transaction_base64' => base64_encode($builderResult['transactionBody']->serializeToString()),
- 'balance' => $user['balance']
- ]), ['type' => 'json']);
- $json = $response->getJson();
- if($json['state'] != 'success') {
- if($json['msg'] == 'session not found') {
- $session->destroy();
- return $this->redirect($this->loginServerUrl . 'account', 303);
- //$this->Flash->error(__('session not found, please login again'));
- } else {
- $this->Flash->error(__('login server return error: ' . json_encode($json)));
- }
- } else {
- $pendingTransactionCount = $session->read('Transactions.pending');
- if($pendingTransactionCount == null) {
- $pendingTransactionCount = 1;
- } else {
- $pendingTransactionCount++;
- }
- $session->write('Transactions.pending', $pendingTransactionCount);
- //echo "pending: " . $pendingTransactionCount;
- if($mode === 'next') {
- return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303);
- } else {
- $this->Flash->success(__('Transaction submitted for review.'));
- }
- }
-
- } catch(\Exception $e) {
- $msg = $e->getMessage();
- $this->Flash->error(__('error http request: ') . $msg);
- }
-
- } else {
- $this->Flash->error(__('No Valid Receiver Public given: ' . $receiverPubKeyHex));
- }
-
-// */
- } else {
- $this->Flash->error(__('Something was invalid, please try again!'));
}
}
-
+
$this->set('timeUsed', microtime(true) - $startTime);
}
diff --git a/community_server/src/Form/AssignRoleForm.php b/community_server/src/Form/AssignRoleForm.php
new file mode 100644
index 000000000..158fa2296
--- /dev/null
+++ b/community_server/src/Form/AssignRoleForm.php
@@ -0,0 +1,30 @@
+addField('role_id', ['type' => 'string']);
+ }
+
+ function validationDefault(Validator $validator)
+ {
+ $validator->setProvider('custom', 'App\Model\Validation\GenericValidation');
+
+ return $validator;
+ }
+
+
+ protected function _execute(array $data)
+ {
+ // Send an email.
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/community_server/src/Form/TransferForm.php b/community_server/src/Form/TransferForm.php
index 5572ddaf9..cb135ab9e 100644
--- a/community_server/src/Form/TransferForm.php
+++ b/community_server/src/Form/TransferForm.php
@@ -1,5 +1,5 @@
-addField('email', ['type' => 'string'])
+ ->addField('group', ['type' => 'string'])
->addField('amount', ['type' => 'decimal', 'precision' => 2])
->addField('memo', ['type' =>'text', 'default' => '', 'rows' => 3, 'maxlength' => 150]);
}
function validationDefault(Validator $validator)
{
- $validator->setProvider('custom', 'App\Model\Validation\TransactionValidation');
+ $validator->setProvider('custom', 'App\Model\Validation\TransactionValidation');
/*
$validator->add('receiver_pubkey_hex', 'length', [
'rule' => ['length', 64],
@@ -34,6 +35,12 @@ class TransferForm extends Form
'rule' => 'email',
'message' => __('A valid email address is required')
])
+ ->add('group', 'custom', [
+ 'rule' => 'alphaNumeric',
+ 'provider' => 'custom',
+ //'message' => __('Only Alpha Numeric Character allowed')
+ 'message' => __('No HTML Tags like > or < please.')
+ ])
->add('memo', 'length', [
'rule' => ['maxLength', 150],
'message' => __('The memo should contain max 150 character')
@@ -54,7 +61,7 @@ class TransferForm extends Form
->allowEmptyString('receiver_pubkey_hex', null, 'create')*/
->add('amount', 'custom', [
'rule' => 'amount',
- 'provider' => 'custom',
+ 'provider' => 'custom',
'message' => __('Please give a valid positive number with maximal 2 decimal places')
]);
return $validator;
@@ -72,4 +79,4 @@ class TransferForm extends Form
// Send an email.
return true;
}
-}
+}
\ No newline at end of file
diff --git a/community_server/src/GPBMetadata/BasicTypes.php b/community_server/src/GPBMetadata/BasicTypes.php
deleted file mode 100644
index f74eb472b..000000000
--- a/community_server/src/GPBMetadata/BasicTypes.php
+++ /dev/null
@@ -1,41 +0,0 @@
-internalAddGeneratedFile(hex2bin(
- "0afe030a10426173696354797065732e70726f746f12166d6f64656c2e6d" .
- "657373616765732e6772616469646f22380a034b657912110a0765643235" .
- "35313918022001280c480012170a0d656432353531395f72656631301803" .
- "2001280c480042050a036b657922580a0d5369676e617475726550616972" .
- "120e0a067075624b657918012001280c12110a0765643235353139180220" .
- "01280c480012170a0d656432353531395f726566313018032001280c4800" .
- "420b0a097369676e617475726522460a0c5369676e61747572654d617012" .
- "360a077369675061697218012003280b32252e6d6f64656c2e6d65737361" .
- "6765732e6772616469646f2e5369676e617475726550616972222b0a0954" .
- "696d657374616d70120f0a077365636f6e6473180120012803120d0a056e" .
- "616e6f7318022001280522230a1054696d657374616d705365636f6e6473" .
- "120f0a077365636f6e647318012001280322590a0c53656e646572416d6f" .
- "756e74121d0a15656432353531395f73656e6465725f7075626b65791801" .
- "2001280c120e0a06616d6f756e74180220012812121a0a1273656e646572" .
- "46696e616c42616c616e636518032001281222410a0e5265636569766572" .
- "416d6f756e74121f0a17656432353531395f72656365697665725f707562" .
- "6b657918012001280c120e0a06616d6f756e74180220012812620670726f" .
- "746f33"
- ), true);
-
- static::$is_initialized = true;
- }
-}
-
diff --git a/community_server/src/GPBMetadata/StateCreateGroup.php b/community_server/src/GPBMetadata/StateCreateGroup.php
deleted file mode 100644
index 7098eb808..000000000
--- a/community_server/src/GPBMetadata/StateCreateGroup.php
+++ /dev/null
@@ -1,32 +0,0 @@
-internalAddGeneratedFile(hex2bin(
- "0ae4010a16537461746543726561746547726f75702e70726f746f12166d" .
- "6f64656c2e6d657373616765732e6772616469646f22a9010a1053746174" .
- "6543726561746547726f7570120c0a046e616d6518012001280912330a0e" .
- "67726f75705075626c69634b657918022001280b321b2e6d6f64656c2e6d" .
- "657373616765732e6772616469646f2e4b657912390a14706172656e7447" .
- "726f75705075626c69634b657918032001280b321b2e6d6f64656c2e6d65" .
- "7373616765732e6772616469646f2e4b65794a0408041005521168656465" .
- "7261436f6e73656e7375734964620670726f746f33"
- ), true);
-
- static::$is_initialized = true;
- }
-}
-
diff --git a/community_server/src/GPBMetadata/StateGroupChangeParent.php b/community_server/src/GPBMetadata/StateGroupChangeParent.php
deleted file mode 100644
index c87782041..000000000
--- a/community_server/src/GPBMetadata/StateGroupChangeParent.php
+++ /dev/null
@@ -1,33 +0,0 @@
-internalAddGeneratedFile(hex2bin(
- "0a8a020a1c537461746547726f75704368616e6765506172656e742e7072" .
- "6f746f12166d6f64656c2e6d657373616765732e6772616469646f22c901" .
- "0a16537461746547726f75704368616e6765506172656e7412330a0e6772" .
- "6f75705075626c69634b657918012001280b321b2e6d6f64656c2e6d6573" .
- "73616765732e6772616469646f2e4b6579123c0a176e6577506172656e74" .
- "47726f75705075626c69634b657918022001280b321b2e6d6f64656c2e6d" .
- "657373616765732e6772616469646f2e4b6579123c0a176f6c6450617265" .
- "6e7447726f75705075626c69634b657918032001280b321b2e6d6f64656c" .
- "2e6d657373616765732e6772616469646f2e4b6579620670726f746f33"
- ), true);
-
- static::$is_initialized = true;
- }
-}
-
diff --git a/community_server/src/GPBMetadata/Transaction.php b/community_server/src/GPBMetadata/Transaction.php
deleted file mode 100644
index d86999450..000000000
--- a/community_server/src/GPBMetadata/Transaction.php
+++ /dev/null
@@ -1,32 +0,0 @@
-internalAddGeneratedFile(hex2bin(
- "0ae4010a115472616e73616374696f6e2e70726f746f12166d6f64656c2e" .
- "6d657373616765732e6772616469646f22ae010a0b5472616e7361637469" .
- "6f6e120a0a026964180120012804123a0a08726563656976656418022001" .
- "280b32282e6d6f64656c2e6d657373616765732e6772616469646f2e5469" .
- "6d657374616d705365636f6e647312340a067369674d617018032001280b" .
- "32242e6d6f64656c2e6d657373616765732e6772616469646f2e5369676e" .
- "61747572654d6170120e0a0674784861736818042001280c12110a09626f" .
- "6479427974657318052001280c620670726f746f33"
- ), true);
-
- static::$is_initialized = true;
- }
-}
-
diff --git a/community_server/src/GPBMetadata/TransactionBody.php b/community_server/src/GPBMetadata/TransactionBody.php
deleted file mode 100644
index 61d99eb96..000000000
--- a/community_server/src/GPBMetadata/TransactionBody.php
+++ /dev/null
@@ -1,46 +0,0 @@
-internalAddGeneratedFile(hex2bin(
- "0a84040a155472616e73616374696f6e426f64792e70726f746f12166d6f" .
- "64656c2e6d657373616765732e6772616469646f1a165374617465437265" .
- "61746547726f75702e70726f746f1a1c537461746547726f75704368616e" .
- "6765506172656e742e70726f746f1a195472616e73616374696f6e437265" .
- "6174696f6e2e70726f746f1a10426173696354797065732e70726f746f22" .
- "e7020a0f5472616e73616374696f6e426f6479120c0a046d656d6f180120" .
- "01280912390a076372656174656418022001280b32282e6d6f64656c2e6d" .
- "657373616765732e6772616469646f2e54696d657374616d705365636f6e" .
- "6473123f0a0b63726561746547726f757018062001280b32282e6d6f6465" .
- "6c2e6d657373616765732e6772616469646f2e5374617465437265617465" .
- "47726f75704800124b0a1167726f75704368616e6765506172656e741807" .
- "2001280b322e2e6d6f64656c2e6d657373616765732e6772616469646f2e" .
- "537461746547726f75704368616e6765506172656e74480012340a087472" .
- "616e7366657218082001280b32202e6d6f64656c2e6d657373616765732e" .
- "6772616469646f2e5472616e736665724800123f0a086372656174696f6e" .
- "18092001280b322b2e6d6f64656c2e6d657373616765732e677261646964" .
- "6f2e5472616e73616374696f6e4372656174696f6e480042060a04646174" .
- "61620670726f746f33"
- ), true);
-
- static::$is_initialized = true;
- }
-}
-
diff --git a/community_server/src/GPBMetadata/TransactionCreation.php b/community_server/src/GPBMetadata/TransactionCreation.php
deleted file mode 100644
index f1ce2cf1a..000000000
--- a/community_server/src/GPBMetadata/TransactionCreation.php
+++ /dev/null
@@ -1,32 +0,0 @@
-internalAddGeneratedFile(hex2bin(
- "0ae6010a195472616e73616374696f6e4372656174696f6e2e70726f746f" .
- "12166d6f64656c2e6d657373616765732e6772616469646f22a8010a1354" .
- "72616e73616374696f6e4372656174696f6e123e0a0e7265636569766572" .
- "416d6f756e7418012001280b32262e6d6f64656c2e6d657373616765732e" .
- "6772616469646f2e5265636569766572416d6f756e7412120a0a6964656e" .
- "745f68617368180220012811123d0a0b7461726765745f64617465180320" .
- "01280b32282e6d6f64656c2e6d657373616765732e6772616469646f2e54" .
- "696d657374616d705365636f6e6473620670726f746f33"
- ), true);
-
- static::$is_initialized = true;
- }
-}
-
diff --git a/community_server/src/GPBMetadata/Transfer.php b/community_server/src/GPBMetadata/Transfer.php
deleted file mode 100644
index b0b2c3a2d..000000000
--- a/community_server/src/GPBMetadata/Transfer.php
+++ /dev/null
@@ -1,31 +0,0 @@
-internalAddGeneratedFile(hex2bin(
- "0abb010a0e5472616e736665722e70726f746f12166d6f64656c2e6d6573" .
- "73616765732e6772616469646f2288010a085472616e73666572123b0a0d" .
- "73656e646572416d6f756e747318012003280b32242e6d6f64656c2e6d65" .
- "7373616765732e6772616469646f2e53656e646572416d6f756e74123f0a" .
- "0f7265636569766572416d6f756e747318022003280b32262e6d6f64656c" .
- "2e6d657373616765732e6772616469646f2e5265636569766572416d6f75" .
- "6e74620670726f746f33"
- ), true);
-
- static::$is_initialized = true;
- }
-}
-
diff --git a/community_server/src/Model/Entity/AddressType.php b/community_server/src/Model/Entity/AddressType.php
index 08dbba281..87d64d61a 100644
--- a/community_server/src/Model/Entity/AddressType.php
+++ b/community_server/src/Model/Entity/AddressType.php
@@ -8,7 +8,7 @@ use Cake\ORM\Entity;
*
* @property int $id
* @property string $name
- * @property string|null $text
+ * @property string $text
*
* @property \App\Model\Entity\StateGroupAddress[] $state_group_addresses
* @property \App\Model\Entity\TransactionGroupAddaddres[] $transaction_group_addaddress
@@ -28,6 +28,6 @@ class AddressType extends Entity
'name' => true,
'text' => true,
'state_group_addresses' => true,
- 'transaction_group_addaddress' => true
+ 'transaction_group_addaddress' => true,
];
}
diff --git a/community_server/src/Model/Entity/BlockchainType.php b/community_server/src/Model/Entity/BlockchainType.php
new file mode 100644
index 000000000..c2e21402c
--- /dev/null
+++ b/community_server/src/Model/Entity/BlockchainType.php
@@ -0,0 +1,30 @@
+ true,
+ 'text' => true,
+ 'symbol' => true,
+ ];
+}
diff --git a/community_server/src/Model/Entity/Role.php b/community_server/src/Model/Entity/Role.php
new file mode 100644
index 000000000..ae0ddd0ba
--- /dev/null
+++ b/community_server/src/Model/Entity/Role.php
@@ -0,0 +1,26 @@
+ true,
+ ];
+}
diff --git a/community_server/src/Model/Entity/StateBalance.php b/community_server/src/Model/Entity/StateBalance.php
index c5fcf5976..a93a0a4b1 100644
--- a/community_server/src/Model/Entity/StateBalance.php
+++ b/community_server/src/Model/Entity/StateBalance.php
@@ -28,6 +28,7 @@ class StateBalance extends Entity
protected $_accessible = [
'state_user_id' => true,
'modified' => true,
+ 'record_date' => true,
'amount' => true,
'record_date' => true,
'state_user' => true
@@ -39,8 +40,12 @@ class StateBalance extends Entity
{
if(method_exists($dateOrTime, 'getTimestamp')) {
return $dateOrTime->getTimestamp();
- } else {
+ } else if(method_exists($dateOrTime, 'i18nFormat')) {
return $dateOrTime->i18nFormat(Time::UNIX_TIMESTAMP_FORMAT);
+ } else {
+ var_dump($dateOrTime);
+ debug_print_backtrace(0, 4);
+ die("date or time unexpected object");
}
}
@@ -53,28 +58,28 @@ class StateBalance extends Entity
// SELECT TIMESTAMPDIFF(SECOND, modified, CURDATE()) AS age_in_seconds from state_balances
// decay_for_duration = decay_factor^seconds
// decay = gradido_cent * decay_for_duration
- $decay_duration = $this->decayDuration(Time::now());
+
+ $decay_duration = intval(Time::now()->getTimestamp() - $this->convertToTimestamp($this->record_date));
if($decay_duration === 0) {
return $this->amount;
}
- return $this->amount;
- //return $this->amount * pow(0.99999997802044727, $decay_duration);
+ //return $this->amount;
+ return $this->amount * pow(0.99999997802044727, $decay_duration);
}
public function partDecay($target_date)
{
- if($target_date == null) return 0;
- $decay_duration = $this->decayDuration($target_date);
+ $decay_duration = intval($this->convertToTimestamp($target_date) - $this->convertToTimestamp($this->record_date));
if($decay_duration <= 0) {
return $this->amount;
}
- return 0;
- //return $this->amount * pow(0.99999997802044727, $decay_duration);
+ //return 0;
+ return $this->amount * pow(0.99999997802044727, $decay_duration);
}
public function decayDuration($target_date)
- {
- if($this->record_date == null) return 0;
- return intval($this->convertToTimestamp($target_date) - $this->record_date->getTimestamp());
+ {
+ return intval($this->convertToTimestamp($target_date) - $this->convertToTimestamp($this->record_date));
}
}
+
diff --git a/community_server/src/Model/Entity/StateGroupAddress.php b/community_server/src/Model/Entity/StateGroupAddress.php
index e5ce71681..e2d669d09 100644
--- a/community_server/src/Model/Entity/StateGroupAddress.php
+++ b/community_server/src/Model/Entity/StateGroupAddress.php
@@ -7,7 +7,7 @@ use Cake\ORM\Entity;
* StateGroupAddress Entity
*
* @property int $id
- * @property int $state_group_id
+ * @property int $group_id
* @property string|resource $public_key
* @property int $address_type_id
*
@@ -26,10 +26,10 @@ class StateGroupAddress extends Entity
* @var array
*/
protected $_accessible = [
- 'state_group_id' => true,
+ 'group_id' => true,
'public_key' => true,
'address_type_id' => true,
'state_group' => true,
- 'address_type' => true
+ 'address_type' => true,
];
}
diff --git a/community_server/src/Model/Entity/StateUserRole.php b/community_server/src/Model/Entity/StateUserRole.php
new file mode 100644
index 000000000..d510bb025
--- /dev/null
+++ b/community_server/src/Model/Entity/StateUserRole.php
@@ -0,0 +1,30 @@
+ true,
+ 'role_id' => true
+ ];
+}
diff --git a/community_server/src/Model/Entity/Transaction.php b/community_server/src/Model/Entity/Transaction.php
index d4ebf68c4..209b8997e 100644
--- a/community_server/src/Model/Entity/Transaction.php
+++ b/community_server/src/Model/Entity/Transaction.php
@@ -39,6 +39,7 @@ class Transaction extends Entity
'tx_hash' => true,
'memo' => true,
'received' => true,
+ 'blockchain_type_id' => true,
'state_group' => true,
'transaction_type' => true,
'state_created' => true,
diff --git a/community_server/src/Model/Entity/TransactionGroupAddaddres.php b/community_server/src/Model/Entity/TransactionGroupAddaddres.php
index 3cb73b9ee..30819209f 100644
--- a/community_server/src/Model/Entity/TransactionGroupAddaddres.php
+++ b/community_server/src/Model/Entity/TransactionGroupAddaddres.php
@@ -28,8 +28,10 @@ class TransactionGroupAddaddres extends Entity
protected $_accessible = [
'transaction_id' => true,
'address_type_id' => true,
+ 'remove_from_group' => true,
'public_key' => true,
'transaction' => true,
- 'address_type' => true
+ 'address_type' => true,
+ 'state_user_id' => true
];
}
diff --git a/community_server/src/Model/Messages/Proto/Gradido/CrossGroupTransfer.php b/community_server/src/Model/Messages/Proto/Gradido/CrossGroupTransfer.php
new file mode 100644
index 000000000..781ac8f25
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/CrossGroupTransfer.php
@@ -0,0 +1,146 @@
+proto.gradido.CrossGroupTransfer
+ */
+class CrossGroupTransfer extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field .proto.gradido.TransferAmount sender = 1;
+ */
+ private $sender = null;
+ /**
+ * Generated from protobuf field bytes receiver = 2;
+ */
+ private $receiver = '';
+ /**
+ * Generated from protobuf field string other_group = 3;
+ */
+ private $other_group = '';
+ /**
+ * this matches related OutboundTransfer.paired_transaction_id
+ *
+ * Generated from protobuf field .proto.gradido.Timestamp paired_transaction_id = 4;
+ */
+ private $paired_transaction_id = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Proto\Gradido\TransferAmount $sender
+ * @type string $receiver
+ * @type string $other_group
+ * @type \Proto\Gradido\Timestamp $paired_transaction_id
+ * this matches related OutboundTransfer.paired_transaction_id
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\GradidoTransfer::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.TransferAmount sender = 1;
+ * @return \Proto\Gradido\TransferAmount
+ */
+ public function getSender()
+ {
+ return $this->sender;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.TransferAmount sender = 1;
+ * @param \Proto\Gradido\TransferAmount $var
+ * @return $this
+ */
+ public function setSender($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\TransferAmount::class);
+ $this->sender = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field bytes receiver = 2;
+ * @return string
+ */
+ public function getReceiver()
+ {
+ return $this->receiver;
+ }
+
+ /**
+ * Generated from protobuf field bytes receiver = 2;
+ * @param string $var
+ * @return $this
+ */
+ public function setReceiver($var)
+ {
+ GPBUtil::checkString($var, False);
+ $this->receiver = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field string other_group = 3;
+ * @return string
+ */
+ public function getOtherGroup()
+ {
+ return $this->other_group;
+ }
+
+ /**
+ * Generated from protobuf field string other_group = 3;
+ * @param string $var
+ * @return $this
+ */
+ public function setOtherGroup($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->other_group = $var;
+
+ return $this;
+ }
+
+ /**
+ * this matches related OutboundTransfer.paired_transaction_id
+ *
+ * Generated from protobuf field .proto.gradido.Timestamp paired_transaction_id = 4;
+ * @return \Proto\Gradido\Timestamp
+ */
+ public function getPairedTransactionId()
+ {
+ return $this->paired_transaction_id;
+ }
+
+ /**
+ * this matches related OutboundTransfer.paired_transaction_id
+ *
+ * Generated from protobuf field .proto.gradido.Timestamp paired_transaction_id = 4;
+ * @param \Proto\Gradido\Timestamp $var
+ * @return $this
+ */
+ public function setPairedTransactionId($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\Timestamp::class);
+ $this->paired_transaction_id = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/GradidoCreation.php b/community_server/src/Model/Messages/Proto/Gradido/GradidoCreation.php
new file mode 100644
index 000000000..9b4c3208d
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/GradidoCreation.php
@@ -0,0 +1,102 @@
+proto.gradido.GradidoCreation
+ */
+class GradidoCreation extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * 40 Byte
+ *
+ * Generated from protobuf field .proto.gradido.TransferAmount receiver = 1;
+ */
+ private $receiver = null;
+ /**
+ * 8 Byte
+ *
+ * Generated from protobuf field .proto.gradido.TimestampSeconds target_date = 3;
+ */
+ private $target_date = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Proto\Gradido\TransferAmount $receiver
+ * 40 Byte
+ * @type \Proto\Gradido\TimestampSeconds $target_date
+ * 8 Byte
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\GradidoCreation::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * 40 Byte
+ *
+ * Generated from protobuf field .proto.gradido.TransferAmount receiver = 1;
+ * @return \Proto\Gradido\TransferAmount
+ */
+ public function getReceiver()
+ {
+ return $this->receiver;
+ }
+
+ /**
+ * 40 Byte
+ *
+ * Generated from protobuf field .proto.gradido.TransferAmount receiver = 1;
+ * @param \Proto\Gradido\TransferAmount $var
+ * @return $this
+ */
+ public function setReceiver($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\TransferAmount::class);
+ $this->receiver = $var;
+
+ return $this;
+ }
+
+ /**
+ * 8 Byte
+ *
+ * Generated from protobuf field .proto.gradido.TimestampSeconds target_date = 3;
+ * @return \Proto\Gradido\TimestampSeconds
+ */
+ public function getTargetDate()
+ {
+ return $this->target_date;
+ }
+
+ /**
+ * 8 Byte
+ *
+ * Generated from protobuf field .proto.gradido.TimestampSeconds target_date = 3;
+ * @param \Proto\Gradido\TimestampSeconds $var
+ * @return $this
+ */
+ public function setTargetDate($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\TimestampSeconds::class);
+ $this->target_date = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/GradidoTransaction.php b/community_server/src/Model/Messages/Proto/Gradido/GradidoTransaction.php
new file mode 100644
index 000000000..b4b34c77e
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/GradidoTransaction.php
@@ -0,0 +1,116 @@
+proto.gradido.GradidoTransaction
+ */
+class GradidoTransaction extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field .proto.gradido.SignatureMap sig_map = 1;
+ */
+ private $sig_map = null;
+ /**
+ * TODO: consider if having concrete type wouldn't be better;
+ * having bytes would better show what is signed, still for
+ * blockchain it doesn't matter, as it has to be serialized again
+ * when validating
+ * UNICORN ANSWER:
+ * Maybe but hedera has at first concrete type and has depracted that now, so is must
+ * be reason for that
+ *
+ * Generated from protobuf field bytes body_bytes = 2;
+ */
+ private $body_bytes = '';
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Proto\Gradido\SignatureMap $sig_map
+ * @type string $body_bytes
+ * TODO: consider if having concrete type wouldn't be better;
+ * having bytes would better show what is signed, still for
+ * blockchain it doesn't matter, as it has to be serialized again
+ * when validating
+ * UNICORN ANSWER:
+ * Maybe but hedera has at first concrete type and has depracted that now, so is must
+ * be reason for that
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\GradidoTransaction::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.SignatureMap sig_map = 1;
+ * @return \Proto\Gradido\SignatureMap
+ */
+ public function getSigMap()
+ {
+ return $this->sig_map;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.SignatureMap sig_map = 1;
+ * @param \Proto\Gradido\SignatureMap $var
+ * @return $this
+ */
+ public function setSigMap($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\SignatureMap::class);
+ $this->sig_map = $var;
+
+ return $this;
+ }
+
+ /**
+ * TODO: consider if having concrete type wouldn't be better;
+ * having bytes would better show what is signed, still for
+ * blockchain it doesn't matter, as it has to be serialized again
+ * when validating
+ * UNICORN ANSWER:
+ * Maybe but hedera has at first concrete type and has depracted that now, so is must
+ * be reason for that
+ *
+ * Generated from protobuf field bytes body_bytes = 2;
+ * @return string
+ */
+ public function getBodyBytes()
+ {
+ return $this->body_bytes;
+ }
+
+ /**
+ * TODO: consider if having concrete type wouldn't be better;
+ * having bytes would better show what is signed, still for
+ * blockchain it doesn't matter, as it has to be serialized again
+ * when validating
+ * UNICORN ANSWER:
+ * Maybe but hedera has at first concrete type and has depracted that now, so is must
+ * be reason for that
+ *
+ * Generated from protobuf field bytes body_bytes = 2;
+ * @param string $var
+ * @return $this
+ */
+ public function setBodyBytes($var)
+ {
+ GPBUtil::checkString($var, False);
+ $this->body_bytes = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/GradidoTransfer.php b/community_server/src/Model/Messages/Proto/Gradido/GradidoTransfer.php
new file mode 100644
index 000000000..a76954c2e
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/GradidoTransfer.php
@@ -0,0 +1,109 @@
+proto.gradido.GradidoTransfer
+ */
+class GradidoTransfer extends \Google\Protobuf\Internal\Message
+{
+ protected $data;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Proto\Gradido\LocalTransfer $local
+ * @type \Proto\Gradido\CrossGroupTransfer $inbound
+ * @type \Proto\Gradido\CrossGroupTransfer $outbound
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\GradidoTransfer::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.LocalTransfer local = 1;
+ * @return \Proto\Gradido\LocalTransfer
+ */
+ public function getLocal()
+ {
+ return $this->readOneof(1);
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.LocalTransfer local = 1;
+ * @param \Proto\Gradido\LocalTransfer $var
+ * @return $this
+ */
+ public function setLocal($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\LocalTransfer::class);
+ $this->writeOneof(1, $var);
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.CrossGroupTransfer inbound = 2;
+ * @return \Proto\Gradido\CrossGroupTransfer
+ */
+ public function getInbound()
+ {
+ return $this->readOneof(2);
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.CrossGroupTransfer inbound = 2;
+ * @param \Proto\Gradido\CrossGroupTransfer $var
+ * @return $this
+ */
+ public function setInbound($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\CrossGroupTransfer::class);
+ $this->writeOneof(2, $var);
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.CrossGroupTransfer outbound = 3;
+ * @return \Proto\Gradido\CrossGroupTransfer
+ */
+ public function getOutbound()
+ {
+ return $this->readOneof(3);
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.CrossGroupTransfer outbound = 3;
+ * @param \Proto\Gradido\CrossGroupTransfer $var
+ * @return $this
+ */
+ public function setOutbound($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\CrossGroupTransfer::class);
+ $this->writeOneof(3, $var);
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getData()
+ {
+ return $this->whichOneof("data");
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/GroupFriendsUpdate.php b/community_server/src/Model/Messages/Proto/Gradido/GroupFriendsUpdate.php
new file mode 100644
index 000000000..22e86d3e1
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/GroupFriendsUpdate.php
@@ -0,0 +1,92 @@
+proto.gradido.GroupFriendsUpdate
+ */
+class GroupFriendsUpdate extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * char[16], alias
+ *
+ * Generated from protobuf field string group = 1;
+ */
+ private $group = '';
+ /**
+ * Generated from protobuf field .proto.gradido.GroupFriendsUpdate.Action action = 2;
+ */
+ private $action = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $group
+ * char[16], alias
+ * @type int $action
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\GroupFriendsUpdate::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * char[16], alias
+ *
+ * Generated from protobuf field string group = 1;
+ * @return string
+ */
+ public function getGroup()
+ {
+ return $this->group;
+ }
+
+ /**
+ * char[16], alias
+ *
+ * Generated from protobuf field string group = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setGroup($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->group = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GroupFriendsUpdate.Action action = 2;
+ * @return int
+ */
+ public function getAction()
+ {
+ return $this->action;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GroupFriendsUpdate.Action action = 2;
+ * @param int $var
+ * @return $this
+ */
+ public function setAction($var)
+ {
+ GPBUtil::checkEnum($var, \Proto\Gradido\GroupFriendsUpdate_Action::class);
+ $this->action = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/GroupFriendsUpdate/Action.php b/community_server/src/Model/Messages/Proto/Gradido/GroupFriendsUpdate/Action.php
new file mode 100644
index 000000000..2a3396c55
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/GroupFriendsUpdate/Action.php
@@ -0,0 +1,51 @@
+proto.gradido.GroupFriendsUpdate.Action
+ */
+class Action
+{
+ /**
+ * Generated from protobuf enum ADD_FRIEND = 0;
+ */
+ const ADD_FRIEND = 0;
+ /**
+ * Generated from protobuf enum REMOVE_FRIEND = 1;
+ */
+ const REMOVE_FRIEND = 1;
+
+ private static $valueToName = [
+ self::ADD_FRIEND => 'ADD_FRIEND',
+ self::REMOVE_FRIEND => 'REMOVE_FRIEND',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
+}
+
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(Action::class, \Proto\Gradido\GroupFriendsUpdate_Action::class);
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/GroupFriendsUpdate_Action.php b/community_server/src/Model/Messages/Proto/Gradido/GroupFriendsUpdate_Action.php
new file mode 100644
index 000000000..24f8cef70
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/GroupFriendsUpdate_Action.php
@@ -0,0 +1,16 @@
+proto.gradido.GroupMemberUpdate
+ */
+class GroupMemberUpdate extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field bytes user_pubkey = 1;
+ */
+ private $user_pubkey = '';
+ /**
+ * Generated from protobuf field .proto.gradido.GroupMemberUpdate.MemberUpdateType member_update_type = 2;
+ */
+ private $member_update_type = 0;
+ /**
+ * this only makes sense for user move, TODO: probably restructure
+ *
+ * Generated from protobuf field .proto.gradido.Timestamp paired_transaction_id = 3;
+ */
+ private $paired_transaction_id = null;
+ /**
+ * Generated from protobuf field string target_group = 4;
+ */
+ private $target_group = '';
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $user_pubkey
+ * @type int $member_update_type
+ * @type \Proto\Gradido\Timestamp $paired_transaction_id
+ * this only makes sense for user move, TODO: probably restructure
+ * @type string $target_group
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\GroupMemberUpdate::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Generated from protobuf field bytes user_pubkey = 1;
+ * @return string
+ */
+ public function getUserPubkey()
+ {
+ return $this->user_pubkey;
+ }
+
+ /**
+ * Generated from protobuf field bytes user_pubkey = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setUserPubkey($var)
+ {
+ GPBUtil::checkString($var, False);
+ $this->user_pubkey = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GroupMemberUpdate.MemberUpdateType member_update_type = 2;
+ * @return int
+ */
+ public function getMemberUpdateType()
+ {
+ return $this->member_update_type;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GroupMemberUpdate.MemberUpdateType member_update_type = 2;
+ * @param int $var
+ * @return $this
+ */
+ public function setMemberUpdateType($var)
+ {
+ GPBUtil::checkEnum($var, \Proto\Gradido\GroupMemberUpdate_MemberUpdateType::class);
+ $this->member_update_type = $var;
+
+ return $this;
+ }
+
+ /**
+ * this only makes sense for user move, TODO: probably restructure
+ *
+ * Generated from protobuf field .proto.gradido.Timestamp paired_transaction_id = 3;
+ * @return \Proto\Gradido\Timestamp
+ */
+ public function getPairedTransactionId()
+ {
+ return $this->paired_transaction_id;
+ }
+
+ /**
+ * this only makes sense for user move, TODO: probably restructure
+ *
+ * Generated from protobuf field .proto.gradido.Timestamp paired_transaction_id = 3;
+ * @param \Proto\Gradido\Timestamp $var
+ * @return $this
+ */
+ public function setPairedTransactionId($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\Timestamp::class);
+ $this->paired_transaction_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field string target_group = 4;
+ * @return string
+ */
+ public function getTargetGroup()
+ {
+ return $this->target_group;
+ }
+
+ /**
+ * Generated from protobuf field string target_group = 4;
+ * @param string $var
+ * @return $this
+ */
+ public function setTargetGroup($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->target_group = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/GroupMemberUpdate/MemberUpdateType.php b/community_server/src/Model/Messages/Proto/Gradido/GroupMemberUpdate/MemberUpdateType.php
new file mode 100644
index 000000000..57580cd75
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/GroupMemberUpdate/MemberUpdateType.php
@@ -0,0 +1,56 @@
+proto.gradido.GroupMemberUpdate.MemberUpdateType
+ */
+class MemberUpdateType
+{
+ /**
+ * Generated from protobuf enum ADD_USER = 0;
+ */
+ const ADD_USER = 0;
+ /**
+ * Generated from protobuf enum MOVE_USER_INBOUND = 1;
+ */
+ const MOVE_USER_INBOUND = 1;
+ /**
+ * Generated from protobuf enum MOVE_USER_OUTBOUND = 2;
+ */
+ const MOVE_USER_OUTBOUND = 2;
+
+ private static $valueToName = [
+ self::ADD_USER => 'ADD_USER',
+ self::MOVE_USER_INBOUND => 'MOVE_USER_INBOUND',
+ self::MOVE_USER_OUTBOUND => 'MOVE_USER_OUTBOUND',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
+}
+
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(MemberUpdateType::class, \Proto\Gradido\GroupMemberUpdate_MemberUpdateType::class);
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/GroupMemberUpdate_MemberUpdateType.php b/community_server/src/Model/Messages/Proto/Gradido/GroupMemberUpdate_MemberUpdateType.php
new file mode 100644
index 000000000..b7080cf75
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/GroupMemberUpdate_MemberUpdateType.php
@@ -0,0 +1,16 @@
+proto.gradido.Key
+ */
+class Key extends \Google\Protobuf\Internal\Message
+{
+ protected $key;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $ed25519
+ * ed25519 signature (libsodium default)
+ * @type string $ed25519_ref10
+ * ed25519 ref10 signature
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\BasicTypes::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * ed25519 signature (libsodium default)
+ *
+ * Generated from protobuf field bytes ed25519 = 2;
+ * @return string
+ */
+ public function getEd25519()
+ {
+ return $this->readOneof(2);
+ }
+
+ /**
+ * ed25519 signature (libsodium default)
+ *
+ * Generated from protobuf field bytes ed25519 = 2;
+ * @param string $var
+ * @return $this
+ */
+ public function setEd25519($var)
+ {
+ GPBUtil::checkString($var, False);
+ $this->writeOneof(2, $var);
+
+ return $this;
+ }
+
+ /**
+ * ed25519 ref10 signature
+ *
+ * Generated from protobuf field bytes ed25519_ref10 = 3;
+ * @return string
+ */
+ public function getEd25519Ref10()
+ {
+ return $this->readOneof(3);
+ }
+
+ /**
+ * ed25519 ref10 signature
+ *
+ * Generated from protobuf field bytes ed25519_ref10 = 3;
+ * @param string $var
+ * @return $this
+ */
+ public function setEd25519Ref10($var)
+ {
+ GPBUtil::checkString($var, False);
+ $this->writeOneof(3, $var);
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getKey()
+ {
+ return $this->whichOneof("key");
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/LocalTransfer.php b/community_server/src/Model/Messages/Proto/Gradido/LocalTransfer.php
new file mode 100644
index 000000000..58f5e23ae
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/LocalTransfer.php
@@ -0,0 +1,85 @@
+proto.gradido.LocalTransfer
+ */
+class LocalTransfer extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field .proto.gradido.TransferAmount sender = 1;
+ */
+ private $sender = null;
+ /**
+ * Generated from protobuf field bytes receiver = 2;
+ */
+ private $receiver = '';
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Proto\Gradido\TransferAmount $sender
+ * @type string $receiver
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\GradidoTransfer::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.TransferAmount sender = 1;
+ * @return \Proto\Gradido\TransferAmount
+ */
+ public function getSender()
+ {
+ return $this->sender;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.TransferAmount sender = 1;
+ * @param \Proto\Gradido\TransferAmount $var
+ * @return $this
+ */
+ public function setSender($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\TransferAmount::class);
+ $this->sender = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field bytes receiver = 2;
+ * @return string
+ */
+ public function getReceiver()
+ {
+ return $this->receiver;
+ }
+
+ /**
+ * Generated from protobuf field bytes receiver = 2;
+ * @param string $var
+ * @return $this
+ */
+ public function setReceiver($var)
+ {
+ GPBUtil::checkString($var, False);
+ $this->receiver = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/SignatureMap.php b/community_server/src/Model/Messages/Proto/Gradido/SignatureMap.php
new file mode 100644
index 000000000..0977169d7
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/SignatureMap.php
@@ -0,0 +1,65 @@
+proto.gradido.SignatureMap
+ */
+class SignatureMap extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Each signature pair corresponds to a unique Key required to sign the transaction.
+ *
+ * Generated from protobuf field repeated .proto.gradido.SignaturePair sigPair = 1;
+ */
+ private $sigPair;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Proto\Gradido\SignaturePair[]|\Google\Protobuf\Internal\RepeatedField $sigPair
+ * Each signature pair corresponds to a unique Key required to sign the transaction.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\BasicTypes::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Each signature pair corresponds to a unique Key required to sign the transaction.
+ *
+ * Generated from protobuf field repeated .proto.gradido.SignaturePair sigPair = 1;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getSigPair()
+ {
+ return $this->sigPair;
+ }
+
+ /**
+ * Each signature pair corresponds to a unique Key required to sign the transaction.
+ *
+ * Generated from protobuf field repeated .proto.gradido.SignaturePair sigPair = 1;
+ * @param \Proto\Gradido\SignaturePair[]|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setSigPair($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Proto\Gradido\SignaturePair::class);
+ $this->sigPair = $arr;
+
+ return $this;
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/SignaturePair.php b/community_server/src/Model/Messages/Proto/Gradido/SignaturePair.php
new file mode 100644
index 000000000..2ef0e81c5
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/SignaturePair.php
@@ -0,0 +1,123 @@
+proto.gradido.SignaturePair
+ */
+class SignaturePair extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field bytes pubKey = 1;
+ */
+ private $pubKey = '';
+ protected $signature;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $pubKey
+ * @type string $ed25519
+ * ed25519 signature (libsodium default)
+ * @type string $ed25519_ref10
+ * ed25519 ref10 signature
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\BasicTypes::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Generated from protobuf field bytes pubKey = 1;
+ * @return string
+ */
+ public function getPubKey()
+ {
+ return $this->pubKey;
+ }
+
+ /**
+ * Generated from protobuf field bytes pubKey = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setPubKey($var)
+ {
+ GPBUtil::checkString($var, False);
+ $this->pubKey = $var;
+
+ return $this;
+ }
+
+ /**
+ * ed25519 signature (libsodium default)
+ *
+ * Generated from protobuf field bytes ed25519 = 2;
+ * @return string
+ */
+ public function getEd25519()
+ {
+ return $this->readOneof(2);
+ }
+
+ /**
+ * ed25519 signature (libsodium default)
+ *
+ * Generated from protobuf field bytes ed25519 = 2;
+ * @param string $var
+ * @return $this
+ */
+ public function setEd25519($var)
+ {
+ GPBUtil::checkString($var, False);
+ $this->writeOneof(2, $var);
+
+ return $this;
+ }
+
+ /**
+ * ed25519 ref10 signature
+ *
+ * Generated from protobuf field bytes ed25519_ref10 = 3;
+ * @return string
+ */
+ public function getEd25519Ref10()
+ {
+ return $this->readOneof(3);
+ }
+
+ /**
+ * ed25519 ref10 signature
+ *
+ * Generated from protobuf field bytes ed25519_ref10 = 3;
+ * @param string $var
+ * @return $this
+ */
+ public function setEd25519Ref10($var)
+ {
+ GPBUtil::checkString($var, False);
+ $this->writeOneof(3, $var);
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSignature()
+ {
+ return $this->whichOneof("signature");
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/Timestamp.php b/community_server/src/Model/Messages/Proto/Gradido/Timestamp.php
new file mode 100644
index 000000000..ae3ecea0e
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/Timestamp.php
@@ -0,0 +1,101 @@
+proto.gradido.Timestamp
+ */
+class Timestamp extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Number of complete seconds since the start of the epoch
+ *
+ * Generated from protobuf field int64 seconds = 1;
+ */
+ private $seconds = 0;
+ /**
+ * Number of nanoseconds since the start of the last second
+ *
+ * Generated from protobuf field int32 nanos = 2;
+ */
+ private $nanos = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type int|string $seconds
+ * Number of complete seconds since the start of the epoch
+ * @type int $nanos
+ * Number of nanoseconds since the start of the last second
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\BasicTypes::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Number of complete seconds since the start of the epoch
+ *
+ * Generated from protobuf field int64 seconds = 1;
+ * @return int|string
+ */
+ public function getSeconds()
+ {
+ return $this->seconds;
+ }
+
+ /**
+ * Number of complete seconds since the start of the epoch
+ *
+ * Generated from protobuf field int64 seconds = 1;
+ * @param int|string $var
+ * @return $this
+ */
+ public function setSeconds($var)
+ {
+ GPBUtil::checkInt64($var);
+ $this->seconds = $var;
+
+ return $this;
+ }
+
+ /**
+ * Number of nanoseconds since the start of the last second
+ *
+ * Generated from protobuf field int32 nanos = 2;
+ * @return int
+ */
+ public function getNanos()
+ {
+ return $this->nanos;
+ }
+
+ /**
+ * Number of nanoseconds since the start of the last second
+ *
+ * Generated from protobuf field int32 nanos = 2;
+ * @param int $var
+ * @return $this
+ */
+ public function setNanos($var)
+ {
+ GPBUtil::checkInt32($var);
+ $this->nanos = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/TimestampSeconds.php b/community_server/src/Model/Messages/Proto/Gradido/TimestampSeconds.php
new file mode 100644
index 000000000..d31aa40d2
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/TimestampSeconds.php
@@ -0,0 +1,67 @@
+proto.gradido.TimestampSeconds
+ */
+class TimestampSeconds extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Number of complete seconds since the start of the epoch
+ *
+ * Generated from protobuf field int64 seconds = 1;
+ */
+ private $seconds = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type int|string $seconds
+ * Number of complete seconds since the start of the epoch
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\BasicTypes::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Number of complete seconds since the start of the epoch
+ *
+ * Generated from protobuf field int64 seconds = 1;
+ * @return int|string
+ */
+ public function getSeconds()
+ {
+ return $this->seconds;
+ }
+
+ /**
+ * Number of complete seconds since the start of the epoch
+ *
+ * Generated from protobuf field int64 seconds = 1;
+ * @param int|string $var
+ * @return $this
+ */
+ public function setSeconds($var)
+ {
+ GPBUtil::checkInt64($var);
+ $this->seconds = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/TransactionBody.php b/community_server/src/Model/Messages/Proto/Gradido/TransactionBody.php
new file mode 100644
index 000000000..b1ad01ea4
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/TransactionBody.php
@@ -0,0 +1,220 @@
+proto.gradido.TransactionBody
+ */
+class TransactionBody extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * max 150 chars
+ *
+ * Generated from protobuf field string memo = 1;
+ */
+ private $memo = '';
+ /**
+ * Generated from protobuf field .proto.gradido.TimestampSeconds created = 2;
+ */
+ private $created = null;
+ /**
+ * Generated from protobuf field uint64 version_number = 3;
+ */
+ private $version_number = 0;
+ protected $data;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $memo
+ * max 150 chars
+ * @type \Proto\Gradido\TimestampSeconds $created
+ * @type int|string $version_number
+ * @type \Proto\Gradido\GradidoTransfer $transfer
+ * @type \Proto\Gradido\GradidoCreation $creation
+ * @type \Proto\Gradido\GroupFriendsUpdate $group_friends_update
+ * @type \Proto\Gradido\GroupMemberUpdate $group_member_update
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\TransactionBody::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * max 150 chars
+ *
+ * Generated from protobuf field string memo = 1;
+ * @return string
+ */
+ public function getMemo()
+ {
+ return $this->memo;
+ }
+
+ /**
+ * max 150 chars
+ *
+ * Generated from protobuf field string memo = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setMemo($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->memo = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.TimestampSeconds created = 2;
+ * @return \Proto\Gradido\TimestampSeconds
+ */
+ public function getCreated()
+ {
+ return $this->created;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.TimestampSeconds created = 2;
+ * @param \Proto\Gradido\TimestampSeconds $var
+ * @return $this
+ */
+ public function setCreated($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\TimestampSeconds::class);
+ $this->created = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field uint64 version_number = 3;
+ * @return int|string
+ */
+ public function getVersionNumber()
+ {
+ return $this->version_number;
+ }
+
+ /**
+ * Generated from protobuf field uint64 version_number = 3;
+ * @param int|string $var
+ * @return $this
+ */
+ public function setVersionNumber($var)
+ {
+ GPBUtil::checkUint64($var);
+ $this->version_number = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GradidoTransfer transfer = 6;
+ * @return \Proto\Gradido\GradidoTransfer
+ */
+ public function getTransfer()
+ {
+ return $this->readOneof(6);
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GradidoTransfer transfer = 6;
+ * @param \Proto\Gradido\GradidoTransfer $var
+ * @return $this
+ */
+ public function setTransfer($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\GradidoTransfer::class);
+ $this->writeOneof(6, $var);
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GradidoCreation creation = 7;
+ * @return \Proto\Gradido\GradidoCreation
+ */
+ public function getCreation()
+ {
+ return $this->readOneof(7);
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GradidoCreation creation = 7;
+ * @param \Proto\Gradido\GradidoCreation $var
+ * @return $this
+ */
+ public function setCreation($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\GradidoCreation::class);
+ $this->writeOneof(7, $var);
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GroupFriendsUpdate group_friends_update = 8;
+ * @return \Proto\Gradido\GroupFriendsUpdate
+ */
+ public function getGroupFriendsUpdate()
+ {
+ return $this->readOneof(8);
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GroupFriendsUpdate group_friends_update = 8;
+ * @param \Proto\Gradido\GroupFriendsUpdate $var
+ * @return $this
+ */
+ public function setGroupFriendsUpdate($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\GroupFriendsUpdate::class);
+ $this->writeOneof(8, $var);
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GroupMemberUpdate group_member_update = 9;
+ * @return \Proto\Gradido\GroupMemberUpdate
+ */
+ public function getGroupMemberUpdate()
+ {
+ return $this->readOneof(9);
+ }
+
+ /**
+ * Generated from protobuf field .proto.gradido.GroupMemberUpdate group_member_update = 9;
+ * @param \Proto\Gradido\GroupMemberUpdate $var
+ * @return $this
+ */
+ public function setGroupMemberUpdate($var)
+ {
+ GPBUtil::checkMessage($var, \Proto\Gradido\GroupMemberUpdate::class);
+ $this->writeOneof(9, $var);
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getData()
+ {
+ return $this->whichOneof("data");
+ }
+
+}
+
diff --git a/community_server/src/Model/Messages/Proto/Gradido/TransferAmount.php b/community_server/src/Model/Messages/Proto/Gradido/TransferAmount.php
new file mode 100644
index 000000000..7673582fa
--- /dev/null
+++ b/community_server/src/Model/Messages/Proto/Gradido/TransferAmount.php
@@ -0,0 +1,85 @@
+proto.gradido.TransferAmount
+ */
+class TransferAmount extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field bytes pubkey = 1;
+ */
+ private $pubkey = '';
+ /**
+ * Generated from protobuf field sint64 amount = 2;
+ */
+ private $amount = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $pubkey
+ * @type int|string $amount
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Gradido\BasicTypes::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Generated from protobuf field bytes pubkey = 1;
+ * @return string
+ */
+ public function getPubkey()
+ {
+ return $this->pubkey;
+ }
+
+ /**
+ * Generated from protobuf field bytes pubkey = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setPubkey($var)
+ {
+ GPBUtil::checkString($var, False);
+ $this->pubkey = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field sint64 amount = 2;
+ * @return int|string
+ */
+ public function getAmount()
+ {
+ return $this->amount;
+ }
+
+ /**
+ * Generated from protobuf field sint64 amount = 2;
+ * @param int|string $var
+ * @return $this
+ */
+ public function setAmount($var)
+ {
+ GPBUtil::checkInt64($var);
+ $this->amount = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/community_server/src/Model/Table/AddressTypesTable.php b/community_server/src/Model/Table/AddressTypesTable.php
index ea0c86d6e..ba94c99c7 100644
--- a/community_server/src/Model/Table/AddressTypesTable.php
+++ b/community_server/src/Model/Table/AddressTypesTable.php
@@ -38,10 +38,10 @@ class AddressTypesTable extends Table
$this->setPrimaryKey('id');
$this->hasMany('StateGroupAddresses', [
- 'foreignKey' => 'address_type_id'
+ 'foreignKey' => 'address_type_id',
]);
$this->hasMany('TransactionGroupAddaddress', [
- 'foreignKey' => 'address_type_id'
+ 'foreignKey' => 'address_type_id',
]);
}
@@ -54,19 +54,20 @@ class AddressTypesTable extends Table
public function validationDefault(Validator $validator)
{
$validator
- ->integer('id')
+ ->nonNegativeInteger('id')
->allowEmptyString('id', null, 'create');
$validator
->scalar('name')
- ->maxLength('name', 25)
+ ->maxLength('name', 45)
->requirePresence('name', 'create')
->notEmptyString('name');
$validator
->scalar('text')
->maxLength('text', 255)
- ->allowEmptyString('text');
+ ->requirePresence('text', 'create')
+ ->notEmptyString('text');
return $validator;
}
diff --git a/community_server/src/Model/Table/BlockchainTypesTable.php b/community_server/src/Model/Table/BlockchainTypesTable.php
new file mode 100644
index 000000000..90213ac9f
--- /dev/null
+++ b/community_server/src/Model/Table/BlockchainTypesTable.php
@@ -0,0 +1,68 @@
+setTable('blockchain_types');
+ $this->setDisplayField('name');
+ $this->setPrimaryKey('id');
+ }
+
+ /**
+ * Default validation rules.
+ *
+ * @param \Cake\Validation\Validator $validator Validator instance.
+ * @return \Cake\Validation\Validator
+ */
+ public function validationDefault(Validator $validator)
+ {
+ $validator
+ ->nonNegativeInteger('id')
+ ->allowEmptyString('id', null, 'create');
+
+ $validator
+ ->scalar('name')
+ ->maxLength('name', 45)
+ ->requirePresence('name', 'create')
+ ->notEmptyString('name');
+
+ $validator
+ ->scalar('text')
+ ->maxLength('text', 255)
+ ->allowEmptyString('text');
+
+ $validator
+ ->scalar('symbol')
+ ->maxLength('symbol', 10)
+ ->allowEmptyString('symbol');
+
+ return $validator;
+ }
+}
diff --git a/community_server/src/Model/Table/RolesTable.php b/community_server/src/Model/Table/RolesTable.php
new file mode 100644
index 000000000..940b7f246
--- /dev/null
+++ b/community_server/src/Model/Table/RolesTable.php
@@ -0,0 +1,72 @@
+setTable('roles');
+ $this->setDisplayField('title');
+ $this->setPrimaryKey('id');
+ }
+
+ /**
+ * Default validation rules.
+ *
+ * @param \Cake\Validation\Validator $validator Validator instance.
+ * @return \Cake\Validation\Validator
+ */
+ public function validationDefault(Validator $validator)
+ {
+ $validator
+ ->integer('id')
+ ->allowEmptyString('id', null, 'create')
+ ->add('id', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
+
+ $validator
+ ->scalar('title')
+ ->maxLength('title', 255)
+ ->allowEmptyString('title');
+
+ return $validator;
+ }
+
+ /**
+ * Returns a rules checker object that will be used for validating
+ * application integrity.
+ *
+ * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
+ * @return \Cake\ORM\RulesChecker
+ */
+ public function buildRules(RulesChecker $rules)
+ {
+ $rules->add($rules->isUnique(['id']));
+
+ return $rules;
+ }
+}
diff --git a/community_server/src/Model/Table/StateBalancesTable.php b/community_server/src/Model/Table/StateBalancesTable.php
index 85b2f7837..cae6e0fe8 100644
--- a/community_server/src/Model/Table/StateBalancesTable.php
+++ b/community_server/src/Model/Table/StateBalancesTable.php
@@ -6,6 +6,10 @@ use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
+use Cake\ORM\TableRegistry;
+use Cake\I18n\Date;
+use Cake\I18n\Time;
+
/**
* StateBalances Model
*
@@ -78,4 +82,271 @@ class StateBalancesTable extends Table
return $rules;
}
+ /*
+ * create new state balance at beginning of next month from $previousStateBalance
+ * calculate decay for the time diff
+ */
+ private function calculateStateBalance($previousStateBalance)
+ {
+ $entity = $this->newEntity();
+ $entity->state_user_id = $previousStateBalance->state_user_id;
+ $newDate = $previousStateBalance->record_date;
+ $newDate->day(1);
+ if($newDate->month <= 12) {
+ $newDate->month($newDate->month + 1);
+ } else {
+ $newDate->month(1);
+ $newDate->year($newDate->year + 1);
+ }
+ $entity->record_date = $newDate;
+ $entity->amount = $previousStateBalance->partDecay($newDate);
+ if($this->save($entity)) {
+ return $entity;
+ }
+ return ['state' => 'error', 'msg' => 'couldn\'t save', 'details' => $entity->getErrors()];
+ }
+
+ public function sortTransactions($a, $b)
+ {
+ if ($a['date'] == $b['date']) {
+ return 0;
+ }
+ return ($a['date'] > $b['date']) ? -1 : 1;
+ }
+ /*
+ * calculate balance at end of month
+ * work only if state balance at begin of month exist
+ * use transaction_send_coins and transaction_creations
+ */
+ public function updateLastStateBalanceOfMonth($month, $year, $state_user_id)
+ {
+ $first_of_month = new Time("$year-$month-01 00:00");
+ $last_of_month = new Time($first_of_month);
+ $last_of_month->addMonth(1);
+ $last_of_month->subSecond(1);
+ $query = $this->find('all')
+ ->where(['AND' => [
+ 'state_user_id' => $state_user_id,
+ 'record_date >=' => $first_of_month,
+ 'record_date <=' => $last_of_month
+ ]])
+ ->order(['record_date' => 'ASC']);
+ if($query->isEmpty()) {
+ return [
+ 'state' => 'error',
+ 'msg' => 'no state balance in this month found',
+ 'details' => [
+ 'month' => $month,
+ 'year' => $year,
+ 'state_user_id' => $state_user_id
+ ]
+ ];
+ }
+ // get transactions from this month
+ $balance_changes = [];
+ $transactionCreationsTable = TableRegistry::getTableLocator()->get('TransactionCreations');
+ $transactionTransfersTable = TableRegistry::getTableLocator()->get('TransactionSendCoins');
+ $relevant_creations = $transactionCreationsTable
+ ->find('all')
+ ->where(['AND' => [
+ 'state_user_id' => $state_user_id,
+ 'target_date >=' => $first_of_month,
+ 'target_date <=' => $last_of_month
+ ]])->contain(false);
+ foreach($relevant_creations as $creation) {
+ $balance_changes[] = ['amount' => $creation->amount, 'date' => $creation->target_date];
+ }
+ $relevant_transfers = $transactionTransfersTable
+ ->find('all')
+ ->where(['AND' => [
+ 'OR' => [
+ 'state_user_id' => $state_user_id,
+ 'receiver_user_id' => $state_user_id
+ ],
+ 'transaction.received >= ' => $first_of_month,
+ 'transaction.received <=' => $last_of_month
+ ]])->contain(['Transactions']);
+ debug($relevant_transfers);
+ foreach($relevant_transfers as $transfer) {
+ $amount = $transfer->amount;
+ // if it is a send transaction, negate the value
+ if($transfer->state_user_id == $state_user_id) {
+ $amount *= -1.0;
+ }
+ $balance_changes[] = ['amount' => $amount, 'date' => $transfer->transaction->received];
+ }
+ uasort($balance_changes, array($this, 'sortTransactions'));
+ $current_state_balance = null;
+ if($query->count() == 1) {
+ $current_state_balance = $this->newEntity();
+ $current_state_balance->amount = $query->first()->amount;
+ $current_state_balance->state_user_id = $state_user_id;
+ $current_state_balance->record_date = $query->first()->record_date;
+ } else if($query->count() == 2) {
+ $array = $query->toArray();
+ $current_state_balance = $array[1];
+ } else {
+ throw new Exception('Should\'n occure, never');
+ }
+
+ foreach($balance_changes as $change) {
+ $current_state_balance->amount = $current_state_balance->getDecay($change['date']);
+ $current_state_balance->amount += $change['amount'];
+ $current_state_balance->record_date = $change['date'];
+ }
+ if(!$this->save($current_state_balance)) {
+ return ['state' => 'error', 'msg' => 'couldn\'t save', 'details' => $current_state_balance->getErrors()];
+ }
+ return $current_state_balance;
+ }
+
+ /*
+ * getting start balance for month
+ * create and create all missing state_balances before if not exist
+ * in while loop
+ */
+
+ public function chooseForMonthAndUser($month, $year, $state_user_id)
+ {
+ $first_of_month = new Time("$year-$month-01 00:00");
+ $last_of_month = new Time($first_of_month);
+ $last_of_month->addMonth(1);
+ $last_of_month->subSecond(1);
+ //echo "first of month: " . $first_of_month->i18nFormat() . ", last of month: " . $last_of_month->i18nFormat() . "
";
+ $query = $this->find('all');
+
+ $query->select([
+ 'month' => $query->func()->month(['record_date' => 'identifier']),
+ 'year' => $query->func()->year(['record_date' => 'identifier'])
+ ])->select($this)
+ //->where(['month' => $month, 'year' => $year, 'state_user_id' => $state_user_id])
+ ->where(['AND' => [
+ 'state_user_id' => $state_user_id,
+ 'record_date >=' => $first_of_month,
+ 'record_date <=' => $last_of_month
+ ]
+ ])
+ ->order(['record_date' => 'ASC'])
+ ->limit(1)
+ ->contain([]);
+ if($query->count() == 0)
+ {
+ // if any state balance for user exist, pick last one
+ $state_balances = $this->find('all')
+ ->where(['state_user_id' => $state_user_id])
+ ->limit(1)
+ ->order(['record_date' => 'DESC'])
+ ;
+ // create one for first user transaction
+ if($state_balances->isEmpty())
+ {
+ $state_user_transactions_table = TableRegistry::getTableLocator()->get('StateUserTransactions');
+ $state_user_transaction = $state_user_transactions_table->find('all')
+ ->where(['state_user_id' => $state_user_id, 'StateUserTransactions.transaction_type_id <' => 3])
+ ->contain(['Transactions' => ['TransactionCreations', 'TransactionSendCoins']])
+ ->limit(1)
+ ->order(['transaction_id' => 'ASC'])
+ ->first()
+ ;
+ if(!$state_user_transaction) {
+ return null;
+ }
+ $entity = $this->newEntity();
+ $entity->state_user_id = $state_user_id;
+ if($state_user_transaction->transaction_type_id == 1) {
+ $creation = $state_user_transaction->transaction->transaction_creations[0];
+ $entity->amount = $creation->amount;
+ $entity->record_date = $creation->target_date;
+ } else if($state_user_transaction->transaction_type_id == 2) {
+ $transfer = $state_user_transaction->transaction->transaction_send_coins[0];
+ $entity->amount = $transfer->amount;
+ $entity->record_date = $state_user_transaction->transaction->received;
+ }
+ if(!$this->save($entity)) {
+ return ['state' => 'error', 'msg' => 'error by saving state balance', 'details' => $entity->getErrors()];
+ }
+ }
+ $state_balances = $this->find('all')
+ ->where(['state_user_id' => $state_user_id])
+ ->limit(1)
+ ->order(['record_date' => 'DESC'])
+ ;
+ if($state_balances->count() == 1)
+ {
+ $current_state_balance = $state_balances->first();
+ while(true)
+ {
+ $new_state_balance_begin = $this->calculateStateBalance($current_state_balance);
+ if(is_array($new_state_balance_begin)) {
+ return ['state' => 'error', 'msg' => 'error calculate state balance', 'details' => $new_state_balance_begin];
+ }
+ $record_date = $new_state_balance_begin->record_date;
+ if($record_date->month === $month && $record_date->year === $year) {
+ return $new_state_balance_begin;
+ }
+ $current_state_balance = $this->updateLastStateBalanceOfMonth($month, $year, $state_user_id);
+ }
+ }
+ else
+ {
+ return ['state' => 'error', 'msg' => 'creation of first state_balance failes'];
+ }
+ }
+ return $query->first();
+ }
+
+ public function updateBalanceWithTransaction($newBalance, $recordDate, $userId)
+ {
+ // max 2 StateBalance Entrys per month:
+ // 1. first of month or first transaction of user
+ // 2. last of month or last transaction of user
+ $first_state_balance_of_month = $this->chooseForMonthAndUser($recordDate->month, $recordDate->year, $userId);
+ $updated_state_balance = null;
+
+ if($first_state_balance_of_month == null || is_array($first_state_balance_of_month)) {
+ return $first_state_balance_of_month;
+ }
+
+ if($first_state_balance_of_month->record_date->day == $recordDate->day &&
+ $recordDate > $first_state_balance_of_month->record_date) {
+ if($first_state_balance_of_month->amount == $newBalance) {
+ // nothing to do here
+ return true;
+ }
+ $updated_state_balance = $first_state_balance_of_month;
+ $updated_state_balance->amount = $newBalance;
+ // copy complete record date, inclusive time
+ $first_state_balance_of_month->record_date = $recordDate;
+ } else {
+ $query = $this->find('all')
+ ->where(['AND' => [
+ 'record_date >' => $first_state_balance_of_month->record_date,
+ 'record_date <=' => $recordDate,
+ 'state_user_id' => $userId
+ ]]);
+ if(!$query->isEmpty()) {
+ $updated_state_balance = $query->first();
+ if($updated_state_balance->record_date == $recordDate) {
+ return true;
+ }
+ } else {
+ $updated_state_balance = $this->newEntity();
+ $updated_state_balance->state_user_id = $userId;
+ }
+ $updated_state_balance->record_date = $recordDate;
+ $updated_state_balance->amount = $newBalance;
+ }
+
+ if($updated_state_balance) {
+ if(!$this->save($updated_state_balance)) {
+ return ['state' => 'error', 'msg' => 'error by saving state balance', 'details' => $entity->getErrors()];
+ }
+
+ // delete all state_balances which came after
+ // they will be automaticlly recovered by next call of chooseForMonthAndUser
+ $this->deleteAll(['state_user_id' => $userId, 'record_date >' => $recordDate]);
+ }
+
+ return true;
+ }
}
diff --git a/community_server/src/Model/Table/StateGroupAddressesTable.php b/community_server/src/Model/Table/StateGroupAddressesTable.php
index 62fcf9470..a63e2ae1c 100644
--- a/community_server/src/Model/Table/StateGroupAddressesTable.php
+++ b/community_server/src/Model/Table/StateGroupAddressesTable.php
@@ -9,7 +9,7 @@ use Cake\Validation\Validator;
/**
* StateGroupAddresses Model
*
- * @property \App\Model\Table\StateGroupsTable&\Cake\ORM\Association\BelongsTo $StateGroups
+ * @property &\Cake\ORM\Association\BelongsTo $Groups
* @property \App\Model\Table\AddressTypesTable&\Cake\ORM\Association\BelongsTo $AddressTypes
*
* @method \App\Model\Entity\StateGroupAddress get($primaryKey, $options = [])
@@ -37,13 +37,13 @@ class StateGroupAddressesTable extends Table
$this->setDisplayField('id');
$this->setPrimaryKey('id');
- $this->belongsTo('StateGroups', [
- 'foreignKey' => 'state_group_id',
- 'joinType' => 'INNER'
- ]);
+ /*$this->belongsTo('Groups', [
+ 'foreignKey' => 'group_id',
+ 'joinType' => 'INNER',
+ ]);*/
$this->belongsTo('AddressTypes', [
'foreignKey' => 'address_type_id',
- 'joinType' => 'INNER'
+ 'joinType' => 'INNER',
]);
}
@@ -56,12 +56,13 @@ class StateGroupAddressesTable extends Table
public function validationDefault(Validator $validator)
{
$validator
- ->integer('id')
+ ->nonNegativeInteger('id')
->allowEmptyString('id', null, 'create');
$validator
->requirePresence('public_key', 'create')
- ->notEmptyString('public_key');
+ ->notEmptyString('public_key')
+ ->add('public_key', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
return $validator;
}
@@ -75,7 +76,8 @@ class StateGroupAddressesTable extends Table
*/
public function buildRules(RulesChecker $rules)
{
- $rules->add($rules->existsIn(['state_group_id'], 'StateGroups'));
+ $rules->add($rules->isUnique(['public_key']));
+ //$rules->add($rules->existsIn(['group_id'], 'Groups'));
$rules->add($rules->existsIn(['address_type_id'], 'AddressTypes'));
return $rules;
diff --git a/community_server/src/Model/Table/StateUserRolesTable.php b/community_server/src/Model/Table/StateUserRolesTable.php
new file mode 100644
index 000000000..895e788b2
--- /dev/null
+++ b/community_server/src/Model/Table/StateUserRolesTable.php
@@ -0,0 +1,86 @@
+setTable('state_user_roles');
+ $this->setPrimaryKey('id');
+
+
+ $this->belongsTo('StateUser', [
+ 'foreignKey' => 'state_user_id',
+ 'joinType' => 'INNER'
+ ]);
+
+ $this->belongsTo('Role', [
+ 'foreignKey' => 'role_id',
+ 'joinType' => 'INNER'
+ ]);
+
+
+ }
+
+ /**
+ * Default validation rules.
+ *
+ * @param \Cake\Validation\Validator $validator Validator instance.
+ * @return \Cake\Validation\Validator
+ */
+ public function validationDefault(Validator $validator)
+ {
+ $validator
+ ->integer('id')
+ ->allowEmptyString('id', null, 'create');
+
+
+
+ return $validator;
+ }
+
+ /**
+ * Returns a rules checker object that will be used for validating
+ * application integrity.
+ *
+ * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
+ * @return \Cake\ORM\RulesChecker
+ */
+ public function buildRules(RulesChecker $rules)
+ {
+ // $rules->add($rules->existsIn(['index_id'], 'Indices'));
+ //$rules->add($rules->existsIn(['state_group_id'], 'StateGroups'));
+
+ return $rules;
+ }
+
+
+}
diff --git a/community_server/src/Model/Table/TransactionGroupAddaddressTable.php b/community_server/src/Model/Table/TransactionGroupAddaddressTable.php
index 3fd03f32a..cb9912083 100644
--- a/community_server/src/Model/Table/TransactionGroupAddaddressTable.php
+++ b/community_server/src/Model/Table/TransactionGroupAddaddressTable.php
@@ -45,6 +45,10 @@ class TransactionGroupAddaddressTable extends Table
'foreignKey' => 'address_type_id',
'joinType' => 'INNER'
]);
+ $this->belongsTo('StateUsers', [
+ 'foreignKey' => 'state_user_id',
+ 'joinType' => 'INNER'
+ ]);
}
/**
@@ -77,6 +81,7 @@ class TransactionGroupAddaddressTable extends Table
{
$rules->add($rules->existsIn(['transaction_id'], 'Transactions'));
$rules->add($rules->existsIn(['address_type_id'], 'AddressTypes'));
+ $rules->add($rules->existsIn(['state_user_id'], 'StateUsers'));
return $rules;
}
diff --git a/community_server/src/Model/Table/TransactionsTable.php b/community_server/src/Model/Table/TransactionsTable.php
index 6777070fe..198feda73 100644
--- a/community_server/src/Model/Table/TransactionsTable.php
+++ b/community_server/src/Model/Table/TransactionsTable.php
@@ -52,6 +52,10 @@ class TransactionsTable extends Table
'foreignKey' => 'transaction_type_id',
'joinType' => 'INNER'
]);
+ $this->belongsTo('BlockchainTypes', [
+ 'foreignKey' => 'blockchain_type_id',
+ 'joinType' => 'INNER'
+ ]);
$this->hasMany('StateCreated', [
'foreignKey' => 'transaction_id'
]);
@@ -114,6 +118,7 @@ class TransactionsTable extends Table
{
$rules->add($rules->existsIn(['state_group_id'], 'StateGroups'));
$rules->add($rules->existsIn(['transaction_type_id'], 'TransactionTypes'));
+ $rules->add($rules->existsIn(['blockchain_type_id'], 'BlockchainTypes'));
return $rules;
}
diff --git a/community_server/src/Model/Transactions/Record.php b/community_server/src/Model/Transactions/Record.php
new file mode 100644
index 000000000..5572730ef
--- /dev/null
+++ b/community_server/src/Model/Transactions/Record.php
@@ -0,0 +1,575 @@
+signature = $signature;
+ $this->publicKey = $pubkey;
+ }
+
+ public function finalize($transactionId)
+ {
+ $signaturesTable = TableRegistry::getTableLocator()->get('TransactionSignatures');
+ $entity = $signaturesTable->newEntity();
+ $entity->transaction_id = $transactionId;
+ if(strlen($this->signature) != 128) {
+ return ['state' => 'error', 'msg' => 'invalid signature size', 'details' => strlen($this->signature)];
+ }
+ if(strlen($this->publicKey) != 64) {
+ return ['state' => 'error', 'msg' => 'invalid pubkey size', 'details' => strlen($this->publicKey)];
+ }
+ if(!preg_match('/^[0-9a-fA-F]*$/', $this->signature)) {
+ return ['state' => 'error', 'msg' => 'signature isn\'t in hex format'];
+ }
+ if(!preg_match('/^[0-9a-fA-F]*$/', $this->publicKey)) {
+ return ['state' => 'error', 'msg' => 'publicKey isn\'t in hex format'];
+ }
+ $entity->signature = hex2bin($this->signature);
+ $entity->pubkey = hex2bin($this->publicKey);
+
+ if(!$signaturesTable->save($entity)) {
+ return ['state' => 'error', 'msg' => 'error saving signature', 'details' => $entity->getErrors()];
+ }
+ return true;
+ }
+}
+
+
+
+class GradidoModifieUserBalance
+{
+ private $state_users = [];
+ private $user_balances = [];
+
+ public function getUserId($userPublicKey)
+ {
+ $stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers');
+
+ $stateUser = $stateUsersTable->find('all')->where(['public_key' => hex2bin($userPublicKey)]);
+ if($stateUser->isEmpty()) {
+ return ['state' => 'error', 'msg' => '[GradidoModifieUserBalance::getUserId] couldn\'t find user via public key'];
+ }
+ $id = $stateUser->first()->id;
+ if($id && is_int($id) && (int)$id > 0 && !in_array((int)$id, $this->state_users)) {
+ array_push($this->state_users, (int)$id);
+ }
+ return $id;
+ }
+
+ public function updateBalance($newBalance, $recordDate, $userId)
+ {
+ $stateBalancesTable = TableRegistry::getTableLocator()->get('StateBalances');
+ $state_balance_query = $stateBalancesTable->find()->where(['state_user_id' => $userId])->order(['record_date ASC']);
+ $state_balance = null;
+ if($state_balance_query->count() > 0) {
+ $state_balance = $state_balance_query->last();
+ } else {
+ $state_balance = $stateBalancesTable->newEntity();
+ $state_balance->state_user_id = $userId;
+ }
+ $state_balance->amount = $newBalance;
+ $state_balance->record_date = $recordDate;
+ $this->user_balances[$userId] = $state_balance;
+ $stateBalancesTable->save($state_balance);
+ return true;
+ //$this->user_balances[$userId] = ['balance' => $newBalance, '']
+ //
+ //return $stateBalancesTable->updateBalanceWithTransaction($newBalance, $recordDate, $userId);
+
+ /*$first_of_month = new Time("$year-$month-01 00:00");
+ $stateBalanceQuery = $stateBalancesTable
+ ->find('all')
+ ->where(['state_user_id' => $userId])
+ ->order(['record_date' => 'DESC'])
+ ->limit(1);
+ $entity = null;
+
+ if(!$stateBalanceQuery->isEmpty()) {
+ $entity = $stateBalanceQuery->first();
+ if($entity->record_date != NULL &&
+ ($entity->record_date > $recordDate || $entity->record_date->day == 1)) {
+ return false;
+ }
+ } else {
+ $entity = $stateBalancesTable->newEntity();
+ $entity->state_user_id = $userId;
+ }
+ $entity->record_date = $recordDate;
+ $entity->amount = $newBalance;
+ /*if(!$stateBalancesTable->save($entity)) {
+ return ['state' => 'error', 'msg' => 'error saving state balance', 'details' => $entity->getErrors()];
+ }*/
+ //return true;
+ }
+
+ public function getAllStateUsers()
+ {
+ return $this->state_users;
+ }
+ public function getAllStateUserBalances()
+ {
+ return $this->user_balances;
+ }
+}
+
+class ManageNodeGroupAdd extends GradidoModifieUserBalance
+{
+ /*
+ "add_user": {
+ "user\": " << user << ",
+ },
+ OR
+
+ "move_user_inbound|move_user_outbound": {
+ "user": " << user << ",
+ "other_group": " << other_group << ",
+ "paired_transaction_id": {
+ "seconds": << ts.seconds <<,
+ "nanos": << ts.nanos
+ }
+ },
+
+ */
+
+ private $user_pubkey;
+ private $other_group = '';
+ private $remove_from_group = false;
+
+ public function __construct($data)
+ {
+ $this->user_pubkey = $data['user'];
+ if(isset($data['other_group'])) {
+ $this->other_group = $data['other_group'];
+ }
+ }
+
+ public function finalize($transactionId, $received)
+ {
+ $transactionGroupAddadressTable = TableRegistry::getTableLocator()->get('TransactionGroupAddaddress');
+ $stateGroupAddresses = TableRegistry::getTableLocator()->get('StateGroupAddresses');
+ $transactionGroupEntity = $transactionGroupAddadressTable->newEntity();
+ if(!is_int($transactionId)) {
+ return ['state' => 'error', 'msg' => '[ManageNodeGroupAdd::finalize] transaction id is not int', 'details' => $transactionId];
+ }
+ $transactionGroupEntity->transaction_id = $transactionId;
+ $transactionGroupEntity->address_type_id = 1;
+ if(strlen($this->user_pubkey) != 64) {
+ return ['state' => 'error', 'msg' => 'invalid size user pubkey', 'details' => strlen($this->user_pubkey)];
+ }
+ if(!preg_match('/^[0-9a-fA-F]*$/', $this->user_pubkey)) {
+ return ['state' => 'error', 'msg' => 'user_pubkey isn\'t in hex format'];
+ }
+
+ $userPubkeyBin = hex2bin($this->user_pubkey);
+
+ $transactionGroupEntity->public_key = $userPubkeyBin;
+ $user_id = $this->getUserId($this->user_pubkey);
+ if(!is_int($user_id)) {
+ return ['state' => 'error', 'msg' => '[ManageNodeGroupAdd::finalize] user id is not int', 'details' => $user_id];
+ }
+ $transactionGroupEntity->state_user_id = $user_id;
+ $transactionGroupEntity->remove_from_group = $this->remove_from_group;
+ if(!$transactionGroupAddadressTable->save($transactionGroupEntity)) {
+ return ['state' => 'error', 'msg' => 'error saving TransactionGroupAddaddress Entity', 'details' => $transactionGroupEntity->getErrors()];
+ }
+
+
+ if($this->remove_from_group) {
+ $stateGroup_query = $stateGroupAddresses->find('all')->where(['public_key' => hex2bin($this->user_pubkey)]);
+ if(!$stateGroup_query->isEmpty()) {
+ $stateGroupAddresses->delete($stateGroup_query->first());
+ }
+ } else {
+ $stateGroupAddressesEntity = $stateGroupAddresses->newEntity();
+ $stateGroupAddressesEntity->group_id = 1;
+ $stateGroupAddressesEntity->public_key = $userPubkeyBin;
+ $stateGroupAddressesEntity->address_type_id = 1;
+ if(!$stateGroupAddresses->save($stateGroupAddressesEntity)) {
+ return ['state' => 'error', 'msg' => 'error saving state group addresses entity', 'details' => $stateGroupAddressesEntity->getErrors()];
+ }
+ }
+
+ return true;
+ }
+
+ public function setRemoveFromGroup($removeFromGroup) {
+ $this->remove_from_group = $removeFromGroup;
+ }
+}
+
+
+class GradidoCreation extends GradidoModifieUserBalance
+{
+ /*
+ * "gradido_creation": {
+ "user": " << user << ",
+ "new_balance": << v.new_balance << ,
+ "prev_transfer_rec_num": << v.prev_transfer_rec_num <<,
+ "amount": << v.amount <<
+ }
+ */
+ private $userPubkey;
+ private $amount;
+ private $targetDate; // seems currently not in node server implementet, use hedera date until it is implemented
+ private $new_balance;
+
+
+ public function __construct($data)
+ {
+ $this->userPubkey = $data['user'];
+ $this->amount = $data['amount']['amount'];
+ $this->new_balance = $data['new_balance']['amount'];
+ //$this->targetDate = $received;
+ }
+
+ public function finalize($transactionId, $received)
+ {
+ // TODO: don't use, after node server transmit correct date
+ $this->targetDate = $received;
+
+ $transactionCreationTable = TableRegistry::getTableLocator()->get('TransactionCreations');
+
+
+ $state_user_id = $this->getUserId($this->userPubkey);
+ if(!is_int($state_user_id)) {
+ return $state_user_id;
+ }
+
+ $entity = $transactionCreationTable->newEntity();
+ $entity->transaction_id = $transactionId;
+ $entity->amount = $this->amount;
+ $entity->target_date = $this->targetDate;
+ $entity->state_user_id = $state_user_id;
+
+ if(!$transactionCreationTable->save($entity)) {
+ return ['state' => 'error', 'msg' => 'error saving create transaction', 'details' => $entity->getErrors()];
+ }
+
+ $balance_result = $this->updateBalance($this->new_balance, $received, $state_user_id);
+ if(is_array($balance_result)) {
+ return $balance_result;
+ }
+
+ return true;
+ }
+
+
+
+}
+
+class GradidoTransfer extends GradidoModifieUserBalance
+{
+ /*
+ "local_transfer|inbound_transfer|outbound_transfer": {
+ "sender": {
+ "user": " << sender << ",
+ "new_balance": << tt.sender.new_balance << ,
+ "prev_transfer_rec_num": << tt.sender.prev_transfer_rec_num <<
+ },
+ "receiver": {
+ "user": " << receiver << ",
+ "new_balance": << tt.receiver.new_balance << ,
+ "prev_transfer_rec_num": << tt.receiver.prev_transfer_rec_num <<
+ },
+ "amount": << tt.amount <<
+ },
+ * */
+ private $amount;
+ private $sender_new_balance = null;
+ private $sender_pubkey;
+
+ private $receiver_pubkey;
+ private $receiver_new_balance = null;
+
+
+ public function __construct($data)
+ {
+ $this->amount = $data['amount']['amount'];
+
+ $sender = $data['sender'];
+ $this->sender_pubkey = $sender['user'];
+ if(isset($sender['new_balance'])) {
+ $this->sender_new_balance = $sender['new_balance']['amount'];
+ }
+
+ $receiver = $data['receiver'];
+ $this->receiver_pubkey = $receiver['user'];
+ if(isset($receiver['new_balance'])) {
+ $this->receiver_new_balance = $receiver['new_balance']['amount'];
+ }
+
+ }
+
+ public function finalize($transactionId, $received)
+ {
+ $transactionTransferTable = TableRegistry::getTableLocator()->get('TransactionSendCoins');
+ if(strlen($this->sender_pubkey) != 64) {
+ return ['state' => 'error', 'msg' => 'invalid size sender pubkey', 'details' => strlen($this->user_pubkey)];
+ }
+ if(!preg_match('/^[0-9a-fA-F]*$/', $this->sender_pubkey)) {
+ return ['state' => 'error', 'msg' => 'sender_pubkey isn\'t in hex format'];
+ }
+ if(strlen($this->receiver_pubkey) != 64) {
+ return ['state' => 'error', 'msg' => 'invalid size receiver pubkey', 'details' => strlen($this->user_pubkey)];
+ }
+ if(!preg_match('/^[0-9a-fA-F]*$/', $this->receiver_pubkey)) {
+ return ['state' => 'error', 'msg' => 'receiver_pubkey isn\'t in hex format'];
+ }
+
+ $sender_id = $this->getUserId($this->sender_pubkey);
+ $receiver_id = $this->getUserId($this->receiver_pubkey);
+ if(is_array($sender_id) && is_array($receiver_id)) {
+ return ['state' => 'error', 'msg' => 'neither sender or receiver known'];
+ }
+ $transferEntity = $transactionTransferTable->newEntity();
+ $transferEntity->transaction_id = $transactionId;
+ $transferEntity->sender_public_key = hex2bin($this->sender_pubkey);
+ $transferEntity->receiver_public_key = hex2bin($this->receiver_pubkey);
+ $transferEntity->amount = $this->amount;
+ if($this->sender_new_balance != null) {
+ $transferEntity->sender_final_balance = $this->sender_new_balance;
+
+ if(is_int($sender_id) && $sender_id > 0) {
+ $transferEntity->state_user_id = $sender_id;
+ $balance_result = $this->updateBalance($this->sender_new_balance, $received, $sender_id);
+ if(is_array($balance_result)) {
+ return $balance_result;
+ }
+ }
+ }
+ if($this->receiver_new_balance != null && is_int($receiver_id) && $receiver_id > 0) {
+ $transferEntity->receiver_user_id = $receiver_id;
+ $balance_result = $this->updateBalance($this->receiver_new_balance, $received, $receiver_id);
+ if(is_array($balance_result)) {
+ return $balance_result;
+ }
+ }
+
+ if(!$transactionTransferTable->save($transferEntity)) {
+ return ['state' => 'error', 'msg' => 'error saving transaction send coins entity', 'details' => $transferEntity->getErrors()];
+ }
+
+ return true;
+ }
+
+}
+
+
+
+
+class Record
+{
+ private $sequenceNumber = 0;
+ private $runningHash = null;
+ private $transactionType = '';
+ private $memo = '';
+ private $signatures = [];
+ private $received;
+ private $transactionObj = null;
+ private $result;
+ private $partCount = 0;
+
+ public function __construct()
+ {
+
+ }
+
+
+ public function parseRecord($json) {
+ if(!isset($json['record_type'])) {
+ return false;
+ }
+ //var_dump($json);
+ switch($json['record_type']) {
+ case 'GRADIDO_TRANSACTION':
+ return $this->parseTransaction($json['transaction']);
+ case 'MEMO':
+ $this->memo .= $json['memo'];
+ return true;
+ case 'SIGNATURES':
+ return $this->parseSignatures($json['signature']);
+ case 'STRUCTURALLY_BAD_MESSAGE':
+ case 'RAW_MESSAGE':
+ case 'BLANK':
+ return false;
+ }
+ }
+
+ /*!
+ * \brief save data parts in db
+ */
+ public function finalize()
+ {
+ $transactionTypesTable = TableRegistry::getTableLocator()->get('TransactionTypes');
+ $transactionsTable = TableRegistry::getTableLocator()->get('Transactions');
+ $stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions');
+
+ $transactionTypeName = $this->nodeTransactionTypeToDBTransactionType($this->transactionType);
+ $transactionTypeResults = $transactionTypesTable->find('all')->where(['name' => $transactionTypeName]);
+ if($transactionTypeResults->isEmpty()) {
+ return [
+ 'state' => 'error', 'msg' => 'transaction type not found',
+ 'details' => ['nodeType' => $this->transactionType, 'dbType' => $transactionTypeName]
+ ];
+ }
+ if(!$this->transactionObj) {
+ return ['state' => 'error', 'msg' => 'transaction obj is null'];
+ }
+ if($this->sequenceNumber <= 0) {
+ return ['state' => 'error', 'msg' => 'sequence number invalid', 'details' => $this->sequenceNumber];
+ }
+ $transactionExistResult = $transactionsTable->find('all')->where(['id' => intval($this->sequenceNumber)]);
+ if(!$transactionExistResult->isEmpty()) {
+ return ['state' => 'warning', 'msg' => 'transaction already exist in db', 'details' => $this->sequenceNumber];
+ }
+ $newTransaction = $transactionsTable->newEntity();
+ $newTransaction->id = $this->sequenceNumber;
+ $newTransaction->transaction_type_id = $transactionTypeResults->first()->id;
+ $newTransaction->memo = $this->memo;
+ if($this->runningHash != '' && strlen($this->runningHash) % 2 == 0) {
+ $newTransaction->tx_hash = hex2bin($this->runningHash);
+ }
+ $newTransaction->received = $this->received;
+
+ //! TODO change into transaction, if at least one fail, rollback
+ /*
+ // In a controller.
+ $articles->getConnection()->transactional(function () use ($articles, $entities) {
+ foreach ($entities as $entity) {
+ $articles->save($entity, ['atomic' => false]);
+ }
+ });
+ */
+ if(!$transactionsTable->save($newTransaction)) {
+ return ['state' => 'error', 'msg' => 'error saving transaction', 'details' => $newTransaction->getErrors()];
+ }
+
+ foreach($this->signatures as $sign) {
+ $sign_result = $sign->finalize($this->sequenceNumber);
+ if($sign_result !== true) {
+ return ['state' => 'error', 'msg', 'error finalizing signature', 'details' => $sign_result];
+ }
+ }
+ $transaction_obj_result = $this->transactionObj->finalize($newTransaction->id, $this->received);
+ if($transaction_obj_result !== true) {
+ return ['state' => 'error', 'msg' => 'error finalizing transaction object', 'details' => $transaction_obj_result];
+ }
+ $state_users = $this->transactionObj->getAllStateUsers();
+ $sut_entities = [];
+ $state_user_balances = $this->transactionObj->getAllStateUserBalances();
+ foreach($state_users as $state_user_id) {
+ $entity = $stateUserTransactionsTable->newEntity();
+ $entity->state_user_id = $state_user_id;
+ $entity->transaction_id = $newTransaction->id;
+ $entity->transaction_type_id = $newTransaction->transaction_type_id;
+ $entity->balance = $state_user_balances[$state_user_id]->amount;
+ $entity->balance_date = $state_user_balances[$state_user_id]->record_date;
+ $sut_entities[] = $entity;
+ }
+ $sut_results = $stateUserTransactionsTable->saveMany($sut_entities);
+ foreach($sut_results as $i => $result) {
+ if(false == $result) {
+ return ['state' => 'error', 'msg' => 'error saving state_user_transaction', 'details' => $sut_entities[$i]->getErrors()];
+ }
+ }
+
+ return true;
+
+ }
+
+ private function nodeTransactionTypeToDBTransactionType($nodeTransactionType)
+ {
+ switch($nodeTransactionType) {
+ case 'GRADIDO_CREATION':
+ return 'creation';
+
+ case 'MOVE_USER_INBOUND':
+ case 'ADD_USER':
+ return 'group add member';
+
+ case 'MOVE_USER_OUTBOUND':
+ return 'group remove member';
+
+ case 'LOCAL_TRANSFER':
+ case 'INBOUND_TRANSFER':
+ case 'OUTBOUND_TRANSFER':
+ return 'transfer';
+ }
+ return 'unknown';
+ }
+
+ private function parseSignatures($signaturesArray)
+ {
+ foreach($signaturesArray as $sign) {
+ $this->signatures[] = new Signature($sign['signature'], $sign['pubkey']);
+ }
+ return true;
+ }
+
+ private function parseTransaction($data)
+ {
+ $this->transactionType = $data['transaction_type'];
+ $sign = $data['signature'];
+ $this->signatures[] = new Signature($sign['signature'], $sign['pubkey']);
+
+ $hedera = $data['hedera_transaction'];
+ $this->sequenceNumber = $hedera['sequenceNumber'];
+ $this->runningHash = $hedera['runningHash'];
+ $this->received = Time::createFromTimestamp($hedera['consensusTimestamp']['seconds']);
+
+ $field_index = '';
+ $class_name = '';
+
+ $removeFromGroup = false;
+ switch($this->transactionType)
+ {
+ case 'GRADIDO_CREATION': $field_index = 'gradido_creation'; $class_name = 'GradidoCreation'; break;
+ case 'ADD_USER': $field_index = 'add_user'; $class_name = 'ManageNodeGroupAdd'; break;
+ case 'MOVE_USER_INBOUND': $field_index = 'move_user_inbound'; $class_name = 'ManageNodeGroupAdd'; break;
+ case 'MOVE_USER_OUTBOUND': $field_index = 'move_user_outbound'; $class_name = 'ManageNodeGroupAdd'; $removeFromGroup = true; break;
+ case 'LOCAL_TRANSFER': $field_index = 'local_transfer'; $class_name = 'GradidoTransfer'; break;
+ case 'INBOUND_TRANSFER': $field_index = 'inbound_transfer'; $class_name = 'GradidoTransfer'; break;
+ case 'OUTBOUND_TRANSFER': $field_index = 'outbound_transfer'; $class_name = 'GradidoTransfer'; break;
+ }
+ if($class_name == '' || $field_index == '') {
+ return ['state' => 'error', 'msg' => 'node transaction type unknown', 'details' => $this->transactionType];
+ }
+ $class_name = 'Model\\Transactions\\' . $class_name;
+ $this->transactionObj = new $class_name($data[$field_index]);
+ if($class_name == 'ManageNodeGroupAdd') {
+ $this->transactionObj->setRemoveFromGroup($removeFromGroup);
+ }
+
+ $this->result = $data['result'];
+ $this->partCount = intval($data['parts']);
+ $this->memo = $data['memo'];
+ return true;
+ }
+
+ public function getSequenceNumber() {
+ return $this->sequenceNumber;
+ }
+ public function getPartCount() {
+ return $this->partCount;
+ }
+
+}
\ No newline at end of file
diff --git a/community_server/src/Model/Transactions/SignatureMap.php b/community_server/src/Model/Transactions/SignatureMap.php
index d8cf35929..cbe48e636 100644
--- a/community_server/src/Model/Transactions/SignatureMap.php
+++ b/community_server/src/Model/Transactions/SignatureMap.php
@@ -29,12 +29,12 @@ class SignatureMap {
static public function fromEntity($transactionSignatures)
{
- $protoSigMap = new \Model\Messages\Gradido\SignatureMap();
+ $protoSigMap = new \Proto\Gradido\SignatureMap();
$sigPairs = $protoSigMap->getSigPair();
//echo "sigPairs: "; var_dump($sigPairs); echo "
";
//return null;
foreach($transactionSignatures as $signature) {
- $sigPair = new \Model\Messages\Gradido\SignaturePair();
+ $sigPair = new \Proto\Gradido\SignaturePair();
$sigPair->setPubKey(stream_get_contents($signature->pubkey));
$sigPair->setEd25519(stream_get_contents($signature->signature));
@@ -46,14 +46,14 @@ class SignatureMap {
static public function build($bodyBytes, array $keys)
{
- $protoSigMap = new \Model\Messages\Gradido\SignatureMap();
+ $protoSigMap = new \Proto\Gradido\SignatureMap();
$sigPairs = $protoSigMap->getSigPair();
//echo "sigPairs: "; var_dump($sigPairs); echo "
";
//return null;
// sign with keys
foreach($keys as $key) {
- $sigPair = new \Model\Messages\Gradido\SignaturePair();
+ $sigPair = new \Proto\Gradido\SignaturePair();
$sigPair->setPubKey(hex2bin($key['pub']));
$sigPair->setEd25519(sodium_crypto_sign_detached($bodyBytes, hex2bin($key['priv'])));
diff --git a/community_server/src/Model/Transactions/Transaction.php b/community_server/src/Model/Transactions/Transaction.php
index 99bd5fae7..da21495b9 100644
--- a/community_server/src/Model/Transactions/Transaction.php
+++ b/community_server/src/Model/Transactions/Transaction.php
@@ -25,7 +25,7 @@ class Transaction extends TransactionBase {
//$transactionBin = base64_decode($base64Data, true);
//if($transactionBin == false) {
//sodium_base64_VARIANT_URLSAFE_NO_PADDING
- if(is_a($base64Data, '\Model\Messages\Gradido\Transaction')) {
+ if(is_a($base64Data, '\Proto\Gradido\Transaction')) {
$this->mProtoTransaction = $base64Data;
$this->mTransactionBody = new TransactionBody($this->mProtoTransaction->getBodyBytes());
return;
@@ -39,6 +39,7 @@ class Transaction extends TransactionBase {
$transactionBin = base64_decode($base64Data, true);
if($transactionBin == false) {
$this->addError('Transaction', $e->getMessage());// . ' ' . $base64Data);
+ $this->addError('base64', $base64Data);
return;
}
}
@@ -49,7 +50,7 @@ class Transaction extends TransactionBase {
$this->addError('Transaction', 'base64 decode error: ' . $base64Data);
} else {
//var_dump($transactionBin);
- $this->mProtoTransaction = new \Model\Messages\Gradido\Transaction();
+ $this->mProtoTransaction = new \Proto\Gradido\GradidoTransaction();
try {
$this->mProtoTransaction->mergeFromString($transactionBin);
//var_dump($this->mProtoTransaction);
@@ -69,11 +70,11 @@ class Transaction extends TransactionBase {
}
}
- static public function build(\Model\Messages\Gradido\TransactionBody $transactionBody, $senderKeyPair)
+ static public function build(\Proto\Gradido\TransactionBody $transactionBody, $senderKeyPair)
{
- $protoTransaction = new \Model\Messages\Gradido\Transaction();
+ $protoTransaction = new \Proto\Gradido\GradidoTransaction();
- $recevied = new \Model\Messages\Gradido\TimestampSeconds();
+ $recevied = new \Proto\Gradido\TimestampSeconds();
$recevied->setSeconds(time());
$protoTransaction->setReceived($recevied);
@@ -197,14 +198,14 @@ class Transaction extends TransactionBase {
'TransactionSignatures'])
->first();
//var_dump($transactionEntry->toArray());
- $protoTransaction = new \Model\Messages\Gradido\Transaction();
+ $protoTransaction = new \Proto\Gradido\Transaction();
$protoTransaction->setId($transactionEntry->id);
- $recevied = new \Model\Messages\Gradido\TimestampSeconds();
+ $recevied = new \Proto\Gradido\TimestampSeconds();
$recevied->setSeconds($transactionEntry->received->getTimestamp());
$protoTransaction->setReceived($recevied);
@@ -228,7 +229,7 @@ class Transaction extends TransactionBase {
}
//echo "verify bodybytes:
" . bin2hex($bodyBytes) . '
';
- $created = new \Model\Messages\Gradido\TimestampSeconds();
+ $created = new \Proto\Gradido\TimestampSeconds();
$created->setSeconds($recevied->getSeconds());
$body->setCreated($created);
$bodyBytes = $body->serializeToString();
diff --git a/community_server/src/Model/Transactions/TransactionBase.php b/community_server/src/Model/Transactions/TransactionBase.php
index 31a26f2ee..3102d2341 100644
--- a/community_server/src/Model/Transactions/TransactionBase.php
+++ b/community_server/src/Model/Transactions/TransactionBase.php
@@ -67,7 +67,7 @@ class TransactionBase {
$stateBalancesTable = self::getTable('stateBalances');
$stateBalanceQuery = $stateBalancesTable
->find('all')
- ->select(['amount', 'id'])
+ ->select(['amount', 'id', 'record_date'])
->contain(false)
->where(['state_user_id' => $stateUserId]);//->first();
//debug($stateBalanceQuery);
@@ -101,9 +101,14 @@ class TransactionBase {
if($stateUserTransactions->count() > 0) {
$stateBalanceTable = self::getTable('state_balances');
+ $state_user_transaction = $stateUserTransactions->first();
+ if(!$state_user_transaction) {
+ $this->addError('TransactionBase::addStateUserTransaction', 'state_user_transaction is zero, no first entry exist?');
+ return false;
+ }
$balance_entity = $stateBalanceTable->newEntity();
- $balance_entity->amount = $stateUserTransactions->first()->balance;
- $balance_entity->record_date = $stateUserTransactions->first()->balance_date;
+ $balance_entity->amount = $state_user_transaction->balance;
+ $balance_entity->record_date = $state_user_transaction->balance_date;
$balance = $balance_entity->decay + $balance;
}
$entity = $stateUserTransactionTable->newEntity();
diff --git a/community_server/src/Model/Transactions/TransactionBody.php b/community_server/src/Model/Transactions/TransactionBody.php
index ef785705c..e0d688dbb 100644
--- a/community_server/src/Model/Transactions/TransactionBody.php
+++ b/community_server/src/Model/Transactions/TransactionBody.php
@@ -12,7 +12,7 @@ class TransactionBody extends TransactionBase {
private $transactionTypeId = 0;
public function __construct($bodyBytes) {
- $this->mProtoTransactionBody = new \Model\Messages\Gradido\TransactionBody();
+ $this->mProtoTransactionBody = new \Proto\Gradido\TransactionBody();
try {
$this->mProtoTransactionBody->mergeFromString($bodyBytes);
// cannot catch Exception with cakePHP, I don't know why
@@ -155,7 +155,7 @@ class TransactionBody extends TransactionBase {
static public function fromEntity($memo, $transaction)
{
- $protoBody = new \Model\Messages\Gradido\TransactionBody();
+ $protoBody = new \Proto\Gradido\TransactionBody();
$protoBody->setMemo($memo);
//$created->setSeconds($var);
@@ -176,7 +176,7 @@ class TransactionBody extends TransactionBase {
static public function build($memo, $specificTransaction)
{
- $protoBody = new \Model\Messages\Gradido\TransactionBody();
+ $protoBody = new \Proto\Gradido\TransactionBody();
$protoBody->setMemo($memo);
if(is_a($specificTransaction, 'TransactionCreation')) {
diff --git a/community_server/src/Model/Transactions/TransactionCreation.php b/community_server/src/Model/Transactions/TransactionCreation.php
index aeac73ce8..54a87e1cb 100644
--- a/community_server/src/Model/Transactions/TransactionCreation.php
+++ b/community_server/src/Model/Transactions/TransactionCreation.php
@@ -26,34 +26,33 @@ class TransactionCreation extends TransactionBase {
return $this->protoTransactionCreation;
}
- static public function build($amount, $memo, $receiver_public_hex, $ident_hash, $targetDate = null)
+ static public function build($amount, $memo, $receiver_public_hex, $targetDate = null)
{
- $receiver = new \Model\Messages\Gradido\ReceiverAmount();
+ $receiver = new \Proto\Gradido\TransferAmount();
$receiver->setAmount($amount);
//$this->receiver_pubkey_hex = $receiver_public_hex;
if(strlen($receiver_public_hex) != 64) {
return ['state' => 'error', 'msg' => 'invalid pubkey'];
}
$pubKeyBin = hex2bin($receiver_public_hex);
- $receiver->setEd25519ReceiverPubkey($pubKeyBin);
+ $receiver->setPubkey($pubKeyBin);
//var_dump($requestData);
- $creationDate = new \Model\Messages\Gradido\TimestampSeconds();
+ $creationDate = new \Proto\Gradido\TimestampSeconds();
$creationDate->setSeconds(time());
- $transactionBody = new \Model\Messages\Gradido\TransactionBody();
+ $transactionBody = new \Proto\Gradido\TransactionBody();
$transactionBody->setMemo($memo);
$transactionBody->setCreated($creationDate);
- $transaction = new \Model\Messages\Gradido\TransactionCreation();
- $transaction->setReceiverAmount($receiver);
- $transaction->setIdentHash($ident_hash);
+ $transaction = new \Proto\Gradido\GradidoTransaction();
+ $transaction->setReceiver($receiver);
//echo "target date: ";
//var_dump($targetDate);
//die('die');
if($targetDate) {
- $targetDateTimestamp = new \Model\Messages\Gradido\TimestampSeconds();
+ $targetDateTimestamp = new \Proto\Gradido\TimestampSeconds();
$targetDateTimestamp->setSeconds($targetDate->getTimestamp());
//var_dump($targetDateTimestamp); die('target');
$transaction->setTargetDate($targetDateTimestamp);
@@ -65,16 +64,13 @@ class TransactionCreation extends TransactionBase {
public function getAmount() {
- return $this->protoTransactionCreation->getReceiverAmount()->getAmount();
+ return $this->protoTransactionCreation->getReceiver()->getAmount();
}
public function getReceiverPublic() {
- return $this->protoTransactionCreation->getReceiverAmount()->getEd25519ReceiverPubkey();
+ return $this->protoTransactionCreation->getReceiver()->getPubkey();
}
- public function getIdentHash() {
- return $this->protoTransactionCreation->getIdentHash();
- }
public function validate($sigPairs) {
@@ -88,54 +84,6 @@ class TransactionCreation extends TransactionBase {
}
}
- // check if creation threshold for this month isn't reached
-
- //$identHashBin = sprintf("%0d", $this->getIdentHash());
- // padding with zero in case hash is smaller than 32 bytes, static length binary field in db
- // ident hash isn't collision ressistent, it is for speed up search
- $identHashBin = pack('a32', $this->getIdentHash());
-
- ////////// old validation not more than 3k GDD for 3 Month ///////////////
- /*$existingCreations = $this->transactionCreationsTable
- ->find('all')
- ->select(['amount', 'state_user_id', 'target_date'])
- ->contain(['StateUsers' => ['fields' => ['StateUsers.public_key']]])
- ->where(['target_date' => NULL]);
- //$targetDate = $this->protoTransactionCreation->getTargetDate();
- //echo "choose existing transactions
";
- //$existingCreations->where([$q->func()->extract('YEAR_MONTH', 'target_date') . ' LIKE ' . $q->func()->extract('YEAR_MONTH', $targetDate)]);
- // ->where(['EXTRACT(YEAR_MONTH FROM target_date) LIKE EXTRACT(YEAR_MONTH FROM']);
- // uncomment because ident hash didn't work at the moment
- //->where(['ident_hash' => $identHashBin]);
- //$existingCreations->select(['amount_sum' => $existingCreations->func()->sum('amount')]);
-
- $existingCreations->matching('Transactions', function ($q) {
-
- return $q->where(
- ['OR' =>
- ['EXTRACT(YEAR_MONTH FROM Transactions.received) LIKE EXTRACT(YEAR_MONTH FROM NOW())',
- 'EXTRACT(YEAR_MONTH FROM DATE_ADD(Transactions.received, INTERVAL 2 MONTH)) LIKE EXTRACT(YEAR_MONTH FROM NOW())']
- ])->select('received');
-
-
- });
- //debug($existingCreations);
- //echo "after choose existing transactions
";
- $newSum = $this->getAmount();
- //var_dump($existingCreations->toArray());
- foreach($existingCreations as $creation) {
- $keyHex = bin2hex(stream_get_contents($creation->state_user->public_key));
- //echo "\ncompare \n$keyHex\nwith: \n". $this->receiver_pubkey_hex."\n";
- if($keyHex == $this->receiver_pubkey_hex) {
- $newSum += $creation->amount;
- }
- }
-
-
- if($newSum > 30000000) {
- $this->addError('TransactionCreation::validate', 'Creation more than 1.000 GDD per Month (3 Month) not allowed');
- return false;
- }//*/
/////////////// new validation, not more than 1K GDD per month via target_date ///////////////////////////
$existingCreations2 = $this->transactionCreationsTable
@@ -204,7 +152,6 @@ class TransactionCreation extends TransactionBase {
}
$transactionCreationEntity->state_user_id = $receiverUserId;
$transactionCreationEntity->amount = $this->getAmount();
- $transactionCreationEntity->ident_hash = $this->getIdentHash();
$transactionCreationEntity->target_date = $this->protoTransactionCreation->getTargetDate()->getSeconds();
if(!$this->transactionCreationsTable->save($transactionCreationEntity)) {
@@ -262,7 +209,7 @@ class TransactionCreation extends TransactionBase {
static public function fromEntity($transactionCreationEntity)
{
- $protoCreation = new \Model\Messages\Gradido\TransactionCreation();
+ $protoCreation = new \Proto\Gradido\GradidoCreation();
//var_dump($transactionCreationEntity);
$stateUsersTable = TableRegistry::getTableLocator()->get('state_users');
@@ -273,12 +220,14 @@ class TransactionCreation extends TransactionBase {
$stateUser = $stateUsersTable->get($userId);
- $receiverAmount = new \Model\Messages\Gradido\ReceiverAmount();
- $receiverAmount->setEd25519ReceiverPubkey(stream_get_contents($stateUser->public_key));
-
+ $receiverAmount = new \Proto\Gradido\TransferAmount();
+ $receiverAmount->setPubkey(stream_get_contents($stateUser->public_key));
$receiverAmount->setAmount($transactionCreationEntity->amount);
- $protoCreation->setReceiverAmount($receiverAmount);
+ $protoCreation->setReceiver($receiverAmount);
+
+ // TODO: add target_date
+ // function currently not used, maybe can even be deleted
//echo "receiver amount: check
";
//$identHashBytes = stream_get_contents($transactionCreationEntity->ident_hash);
diff --git a/community_server/src/Model/Transactions/TransactionTransfer.php b/community_server/src/Model/Transactions/TransactionTransfer.php
index b9182c3ba..c8e9e7973 100644
--- a/community_server/src/Model/Transactions/TransactionTransfer.php
+++ b/community_server/src/Model/Transactions/TransactionTransfer.php
@@ -22,9 +22,8 @@ class TransactionTransfer extends TransactionBase {
{
// repeated SenderAmount senderAmounts = 1;
// repeated ReceiverAmount receiverAmounts = 2;
- $receiver = new \Model\Messages\Gradido\ReceiverAmount();
- $sender = new \Model\Messages\Gradido\SenderAmount();
- $receiver->setAmount($amount);
+
+ $sender = new \Proto\Gradido\TransferAmount();
$sender->setAmount($amount);
if(strlen($receiver_public_hex) != 64) {
@@ -34,71 +33,56 @@ class TransactionTransfer extends TransactionBase {
return ['state' => 'error', 'msg' => 'invalid sender pubkey'];
}
$receiverPubKeyBin = hex2bin($receiver_public_hex);
- $receiver->setEd25519ReceiverPubkey($receiverPubKeyBin);
$senderPubKeyBin = hex2bin($sender_public_hex);
- $sender->setEd25519SenderPubkey($senderPubKeyBin);
+ $sender->setPubkey($senderPubKeyBin);
//var_dump($requestData);
- $creationDate = new \Model\Messages\Gradido\TimestampSeconds();
+ $creationDate = new \Proto\Gradido\TimestampSeconds();
$creationDate->setSeconds(time());
- $transactionBody = new \Model\Messages\Gradido\TransactionBody();
+ $transactionBody = new \Proto\Gradido\TransactionBody();
$transactionBody->setMemo($memo);
$transactionBody->setCreated($creationDate);
- $transaction = new \Model\Messages\Gradido\Transfer();
- $transaction->setReceiverAmounts([$receiver]);
- $transaction->setSenderAmounts([$sender]);
- $transactionBody->setTransfer($transaction);
+ $transfer = new \Proto\Gradido\GradidoTransfer();
+ $local_transfer = new \Proto\Gradido\LocalTransfer();
+ $local_transfer->setReceiver($receiverPubKeyBin);
+ $local_transfer->setSender($sender);
+ $transfer->setLocal($local_transfer);
+ $transactionBody->setTransfer($transfer);
return ['state' => 'success', 'transactionBody' => $transactionBody];
}
public function validate($sigPairs) {
- //$this->addError('TransactionTransfer::validate', 'not implemented yet');
- //return false;
- //$time = microtime(true);
- static $functionName = 'TransactionCreation::validate';
- /*
- * // check signature(s)
- foreach($sigPairs as $sigPair) {
- //echo 'sig Pair: '; var_dump($sigPair); echo "
";
- $pubkey = $sigPair->getPubKey();
- $signature = $sigPair->getEd25519();
- if (!\Sodium\crypto_sign_verify_detached($signature, $bodyBytes, $pubkey)) {
- $this->addError('Transaction::validate', 'signature for key ' . bin2hex($pubkey) . ' isn\'t valid ' );
- return false;
- }
- }
- */
- $sigPubHexs = [];
- foreach($sigPairs as $sigPair) {
- //echo 'sig Pair: '; var_dump($sigPair); echo "
";
- $pubkey = bin2hex($sigPair->getPubKey());
- //$hash = TransactionCreation::DRMakeStringHash($pubkey);
- $hash = $pubkey;
- if(!isset($sigPubHexs[$hash])) {
- $sigPubHexs[$hash] = [$pubkey];
- } else {
- array_push($sigPubHexs[$hash], $pubkey);
- }
- //array_push($sigPubHexs, $pubkey);
- }
-
- $stateUsersTable = TableRegistry::getTableLocator()->get('state_users');
- $senderAmounts = $this->protoTransactionTransfer->getSenderAmounts();
- $senderSum = 0;
- $receiverSum = 0;
-
- $senderPublics = [];
- foreach($senderAmounts as $i => $senderAmount) {
- $senderPublic = $senderAmount->getEd25519SenderPubkey();
- $senderPublicHex = bin2hex($senderPublic);
- array_push($senderPublics, $senderPublic);
+ //$this->addError('TransactionTransfer::validate', 'not implemented yet');
+ //return false;
+ //$time = microtime(true);
+ static $functionName = 'TransactionCreation::validate';
+ $sigPubHexs = [];
+ foreach($sigPairs as $sigPair)
+ {
+ $pubkey = $sigPair->getPubKey();
+ $pubkey_hex = bin2hex($pubkey);
+ //$hash = TransactionCreation::DRMakeStringHash($pubkey);
+ $hash = $pubkey_hex;
+ if(!isset($sigPubHexs[$hash])) {
+ $sigPubHexs[$hash] = [$pubkey_hex];
+ } else {
+ array_push($sigPubHexs[$hash], $pubkey_hex);
+ }
+ //array_push($sigPubHexs, $pubkey);
+ }
+
+ $stateUsersTable = TableRegistry::getTableLocator()->get('state_users');
+ $local_transfer = $this->protoTransactionTransfer->getLocal();
+ $sender = $local_transfer->getSender();
+ $senderPublic = $sender->getPubkey();
+ $senderPublicHex = bin2hex($senderPublic);
if(strlen($senderPublicHex) != 64) {
- $this->addError($functionName, 'invalid sender public key');
- return false;
+ $this->addError($functionName, 'invalid sender public key');
+ return false;
}
// check if signature exist for sender
//$hash = TransactionCreation::DRMakeStringHash($senderPublicHex);
@@ -108,7 +92,7 @@ class TransactionTransfer extends TransactionBase {
return false;
}
// check if sender has enough Gradido
- $amount = $senderAmount->getAmount();
+ $amount = $sender->getAmount();
$user = $stateUsersTable
->find('all')
->select(['id'])
@@ -123,66 +107,37 @@ class TransactionTransfer extends TransactionBase {
$this->addError($functionName, 'sender ' . $i . ' hasn\t enough GDD');
return false;
}
- $senderSum += $amount;
- }
- $uniqueSenderPublics = array_unique($senderPublics);
- if(count($senderPublics) !== count($uniqueSenderPublics)) {
- $this->addError($functionName, 'duplicate sender public key');
- return false;
- }
- $receiverAmounts = $this->protoTransactionTransfer->getReceiverAmounts();
- $receiverPublics = [];
- foreach($receiverAmounts as $reveiverAmount) {
- if(strlen($reveiverAmount->getEd25519ReceiverPubkey()) != 32) {
+ $receiver_public_key = $local_transfer->getReceiver();
+ if(strlen($receiver_public_key) != 32) {
$this->addError($functionName, 'invalid receiver public key');
return false;
}
- array_push($receiverPublics, $reveiverAmount->getEd25519ReceiverPubkey());
- $receiverSum += $reveiverAmount->getAmount();
- }
- $uniqueReceiverPublic = array_unique($receiverPublics);
- if(count($uniqueReceiverPublic) !== count($receiverPublics)) {
- $this->addError($functionName, 'duplicate receiver public key');
- return false;
- }
- $uniquePublics = array_unique(array_merge($receiverPublics, $senderPublics));
- if(count($uniquePublics) !== count($senderPublics) + count($receiverPublics)) {
- // means at least one sender is the same as one receiver
- $this->addError($functionName, 'duplicate public in sender and receiver');
- return false;
- }
- if($senderSum !== $receiverSum) {
- $this->addError($functionName, 'sender amount doesn\'t match receiver amount');
- return false;
- }
- if($senderSum < 0) {
- $this->addError($functionName, 'negative amount not supported');
- return false;
- }
- //die("\n");
- return true;
+ // check if receiver exist
+ $receiver_user = $stateUsersTable->find('all')->select(['id'])->where(['public_key' => $receiver_public_key])->first();
+ if(!$receiver_user) {
+ $this->addError($functionName, 'couldn\'t find receiver ' . $i .' in db' );
+ return false;
+ }
+ if($amount < 0) {
+ $this->addError($functionName, 'negative amount not supported');
+ return false;
+ }
+ return true;
}
public function save($transaction_id, $firstPublic, $received) {
static $functionName = 'TransactionCreation::save';
+ $local_transfer = $this->protoTransactionTransfer->getLocal();
- if(count($this->protoTransactionTransfer->getSenderAmounts()) !== 1) {
- $this->addError($functionName, 'not more than one sender currently supported');
- return false;
- }
- $senderAmount = $this->protoTransactionTransfer->getSenderAmounts()[0];
+ $senderAmount = $local_transfer->getSender();
+ $receiver = $local_transfer->getReceiver();
- if(count($this->protoTransactionTransfer->getReceiverAmounts()) !== 1) {
- $this->addError($functionName, 'not more than one receiver currently supported');
- return false;
- }
- $receiverAmount = $this->protoTransactionTransfer->getReceiverAmounts()[0];
$transactionTransferTable = TableRegistry::getTableLocator()->get('TransactionSendCoins');
- $senderUserId = $this->getStateUserId($senderAmount->getEd25519SenderPubkey());
- $receiverUserId = $this->getStateUserId($receiverAmount->getEd25519ReceiverPubkey());
+ $senderUserId = $this->getStateUserId($senderAmount->getPubkey());
+ $receiverUserId = $this->getStateUserId($receiver);
if($senderUserId === NULL || $receiverUserId === NULL) {
return false;
@@ -192,14 +147,14 @@ class TransactionTransfer extends TransactionBase {
if(false === $finalSenderBalance) {
return false;
}
- if(false === $this->updateStateBalance($receiverUserId, $receiverAmount->getAmount(), $received)) {
+ if(false === $this->updateStateBalance($receiverUserId, $senderAmount->getAmount(), $received)) {
return false;
}
$transactionTransferEntity = $transactionTransferTable->newEntity();
$transactionTransferEntity->transaction_id = $transaction_id;
$transactionTransferEntity->state_user_id = $senderUserId;
- $transactionTransferEntity->receiver_public_key = $receiverAmount->getEd25519ReceiverPubkey();
+ $transactionTransferEntity->receiver_public_key = $receiver;
$transactionTransferEntity->receiver_user_id = $receiverUserId;
$transactionTransferEntity->amount = $senderAmount->getAmount();
$transactionTransferEntity->sender_final_balance = $finalSenderBalance;
@@ -227,10 +182,11 @@ class TransactionTransfer extends TransactionBase {
$disable_email = Configure::read('disableEmail', false);
if($disable_email) return true;
- $senderAmount = $this->protoTransactionTransfer->getSenderAmounts()[0];
- $receiverAmount = $this->protoTransactionTransfer->getReceiverAmounts()[0];
- $senderUserId = $this->getStateUserId($senderAmount->getEd25519SenderPubkey());
- $receiverUserId = $this->getStateUserId($receiverAmount->getEd25519ReceiverPubkey());
+ $local_transfer = $this->protoTransactionTransfer->getLocal();
+ $sender = $local_transfer->getSender();
+ $senderAmount = $sender->getAmount();
+ $senderUserId = $this->getStateUserId($sender->getPubkey());
+ $receiverUserId = $this->getStateUserId($local_transfer->getReceiver());
$receiverUser = $this->getStateUser($receiverUserId);
$senderUser = $this->getStateUser($senderUserId);
@@ -242,7 +198,7 @@ class TransactionTransfer extends TransactionBase {
$emailViewBuilder->setTemplate('notificationTransfer')
->setVars(['receiverUser' => $receiverUser,
'senderUser' => $senderUser,
- 'gdd_cent' => $receiverAmount->getAmount(),
+ 'gdd_cent' => $senderAmount,
'memo' => $memo]);
$receiverNames = $receiverUser->getNames();
if($receiverNames == '' || $receiverUser->email == '') {
@@ -263,7 +219,7 @@ class TransactionTransfer extends TransactionBase {
static public function fromEntity($transactionTransferEntity)
{
- $protoTransfer = new \Model\Messages\Gradido\Transfer();
+ $protoTransfer = new \Proto\Gradido\GradidoTransfer();
$stateUsersTable = TableRegistry::getTableLocator()->get('state_users');
diff --git a/community_server/src/Template/AddressTypes/add.ctp b/community_server/src/Template/AddressTypes/add.ctp
index 7422b666a..f62c5115e 100644
--- a/community_server/src/Template/AddressTypes/add.ctp
+++ b/community_server/src/Template/AddressTypes/add.ctp
@@ -4,8 +4,8 @@
* @var \App\Model\Entity\AddressType $addressType
*/
?>
-