From 9fcf24ba51c5b23150b5966d4ed67a459ad2b301 Mon Sep 17 00:00:00 2001 From: Sebastian Brix Date: Mon, 14 Feb 2022 14:33:49 +0100 Subject: [PATCH] - added type annotations - checked code with psalm --- composer.json | 28 +++--- composer.lock | 186 ++++++++++++++++++++++++++++++++++++--- psalm.xml | 15 ++++ src/Connection.php | 70 +++++++++++---- src/RemoteConnection.php | 51 +++++------ 5 files changed, 276 insertions(+), 74 deletions(-) create mode 100644 psalm.xml diff --git a/composer.json b/composer.json index 007c143..f1c24cd 100644 --- a/composer.json +++ b/composer.json @@ -1,16 +1,18 @@ { - "name": "graphit/graph-client", - "type": "library", - "authors": [ - { - "name": "Graph-IT", - "email": "info@graph-it.com" + "name": "graphit/graph-client", + "type": "library", + "description": "Graph Client", + "authors": [ + { + "name": "Graph-IT", + "email": "info@graph-it.com" + } + ], + "require": { + "php": ">=5.6.0", + "graphit/graph-common": "^0.1.0" + }, + "autoload": { + "psr-4": { "Graphit\\Graph\\Client\\": "src/" } } - ], - "require": { - "graphit/graph-common": "dev-master" - }, - "autoload": { - "psr-4": { "Graphit\\Graph\\Client\\": "src/" } - } } diff --git a/composer.lock b/composer.lock index b45a5bc..dbce69c 100644 --- a/composer.lock +++ b/composer.lock @@ -1,21 +1,22 @@ { "_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#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ea6b729336e3f588b73de24a48480b85", + "content-hash": "c27737b66cf149fe0e8b38e332ff3394", "packages": [ { "name": "graphit/graph-common", - "version": "dev-master", + "version": "v0.1.0", "source": { "type": "git", - "url": "ssh://git@git.graph-it.com/graphit/graph-common", - "reference": "96f2657f44cefb3aa5c1de2b2ea95d9411a13098" + "url": "ssh://git@git.graph-it.com:44022/graphit/graph-common", + "reference": "48d5e16c3a0afbdceef1ace82a69f100c61d7a22" }, "require": { - "php": ">=5.6.0" + "php": ">=5.6.0", + "twig/twig": "^1.26.0" }, "type": "library", "autoload": { @@ -30,17 +31,178 @@ } ], "description": "Vom Graphserver und -Client geteilte Sourcen.", - "time": "2017-08-18T12:42:07+00:00" + "time": "2022-02-10T13:49:02+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "30885182c981ab175d4d034db0f6f469898070ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "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.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-10-20T20:35:02+00:00" + }, + { + "name": "twig/twig", + "version": "v1.44.6", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "ae39480f010ef88adc7938503c9b02d3baf2f3b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/ae39480f010ef88adc7938503c9b02d3baf2f3b3", + "reference": "ae39480f010ef88adc7938503c9b02d3baf2f3b3", + "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.6" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2021-11-25T13:31:46+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "graphit/graph-common": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [] + "platform": { + "php": ">=5.6.0" + }, + "platform-dev": [], + "plugin-api-version": "2.2.0" } diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..3240886 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/src/Connection.php b/src/Connection.php index 2b4567d..608f508 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -7,17 +7,26 @@ use Graphit\Graph\Common\ConnectionInterface; class Connection extends RemoteConnection implements ConnectionInterface { /** @var string */ - protected $url; + private $url; - /** @var resource */ - protected $socket; + /** @var resource|false */ + private $socket = false; - /** @var string */ - protected $protocoll; + /** @var array */ + private $options; /** @var string */ - protected $cryptoType; + private $protocoll; + + /** @var int|false */ + private $cryptoType; + + /** @var int */ + private $messageId = 0; + /** + * @param string $url + */ public function __construct($url, array $options = []) { $this->url = $url; @@ -32,7 +41,7 @@ class Connection extends RemoteConnection implements ConnectionInterface { $this->cryptoType = false; $cryptoTypes = [ - 'tls' => STREAM_CRYPTO_METHOD_TLS_CLIENT, + 'tls' => STREAM_CRYPTO_METHOD_TLS_CLIENT, ]; if (isset($cryptoTypes[$this->protocoll])) { $this->cryptoType = $cryptoTypes[$this->protocoll]; @@ -46,11 +55,12 @@ class Connection extends RemoteConnection implements ConnectionInterface { } } - protected function _connect() + /** @return void */ + private function _connect() { $context = stream_context_create(); - if ($this->cryptoType) { + if ($this->cryptoType !== false) { stream_context_set_option($context, [ 'ssl' => [ 'verify_peer' => true, @@ -62,14 +72,23 @@ class Connection extends RemoteConnection implements ConnectionInterface { ]); } - $this->socket = stream_socket_client($this->url, $errno, $errstr, ini_get('default_socket_timeout'), STREAM_CLIENT_CONNECT, $context); + $timeout = (float)ini_get('default_socket_timeout'); + $this->socket = stream_socket_client($this->url, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context); if ($this->socket === false) { throw new \Exception("stream_socket_server() failed: $errstr\n"); } $this->_readMessage(); } - protected function _readBytes($size) { + /** + * @param int $size + * @return string + */ + private function _readBytes($size) { + if ( !$this->socket) { + throw new \Exception("Socket not initialized"); + } + $bytes = ''; while (strlen($bytes) < $size) { $fread = fread($this->socket, $size - strlen($bytes)); @@ -84,15 +103,25 @@ class Connection extends RemoteConnection implements ConnectionInterface { return $bytes; } - protected function _readMessage() { + /** @return mixed */ + private function _readMessage() { $size = $this->_readBytes(4); + /** @var int $size */ $size = unpack('Vsize', $size)['size']; $message = $this->_readBytes($size); return msgpack_unpack($message); } - protected function _writeBytes($bytes) { + /** + * @param string $bytes + * @return void + */ + private function _writeBytes($bytes) { + if ( !$this->socket) { + throw new \Exception("Socket not initialized"); + } + $size = strlen($bytes); for ($written = 0; $written < strlen($bytes); $written += $fwrite) { $fwrite = fwrite($this->socket, substr($bytes, $written)); @@ -101,11 +130,16 @@ class Connection extends RemoteConnection implements ConnectionInterface { } } if ($written != $size) { - throw new \Exception("Unable to write $size Bytes request to socket"); + throw new \Exception("Unable to write $size Bytes to socket"); } } - protected function _writeMessage($message) { + /** + * @param mixed $message + * @return void + */ + private function _writeMessage($message) { + /** @var string $message */ $message = msgpack_pack($message); $message = pack('V', strlen($message)).$message; $this->_writeBytes($message); @@ -114,8 +148,6 @@ class Connection extends RemoteConnection implements ConnectionInterface { /** */ protected function call($method, array $params) { - static $id = 0; - if ( !$this->socket) { $this->_connect(); } @@ -124,7 +156,7 @@ class Connection extends RemoteConnection implements ConnectionInterface { 'jsonrpc' => '2.0', 'method' => $method, 'params' => $params, - 'id' => ++$id, + 'id' => ++$this->messageId, ]; $this->_writeMessage($request); @@ -133,7 +165,7 @@ class Connection extends RemoteConnection implements ConnectionInterface { throw new \Exception('Not a JSON-RPC 2.0 response!'); } if (isset($response['error'])) { - $error = implode(' ', $response['error']); + $error = json_encode($response['error']); throw new \Exception("JSON-RPC: Remote error: {$error}"); } if ( !isset($response['id']) || $response['id'] != $request['id']) { diff --git a/src/RemoteConnection.php b/src/RemoteConnection.php index 4f9e798..d868fed 100644 --- a/src/RemoteConnection.php +++ b/src/RemoteConnection.php @@ -24,43 +24,43 @@ abstract class RemoteConnection implements ConnectionInterface */ protected abstract function call($method, array $params); - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function erzeuge($knoten_typ) { return $this->call('erzeuge', array($knoten_typ)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function vernichte($node_guid) { return $this->call('vernichte', array($node_guid)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function knotentyp($node_guid) { return $this->call('knotentyp', array($node_guid)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function setze($node_guid, $attributknoten_typ, $wert) { return $this->call('setze', array($node_guid, $attributknoten_typ, $wert)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function attribut($node_guid, $attributknoten_typ) { return $this->call('attribut', array($node_guid, $attributknoten_typ)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function attribute($node_guid, $knoten_typ, $attribute) { return $this->call('attribute', array($node_guid, $knoten_typ, $attribute)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function attributsknoten($attributknoten_typ, $wert) { return $this->call('attributsknoten', array($attributknoten_typ, $wert)); @@ -72,97 +72,89 @@ abstract class RemoteConnection implements ConnectionInterface return $this->call('berechne', array($node_guid, $datenfunktion_name)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function verknuepfe($node_guid1, $node_guid2) { return $this->call('verknuepfe', array($node_guid1, $node_guid2)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function entknuepfe($node_guid1, $node_guid2) { return $this->call('entknuepfe', array($node_guid1, $node_guid2)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function knoten($node_guid, $knoten_typ) { return $this->call('knoten', array($node_guid, $knoten_typ)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function liste($node_guid, $knoten_typ, $reihenfolge = false, $eingrenzung = false, array $parameter = array()) { return $this->call('liste', array($node_guid, $knoten_typ, $reihenfolge, $eingrenzung, $parameter)); } /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function listeattribute($node_guid, $knoten_typ, $attribute, $reihenfolge = false, $eingrenzung = false, array $parameter = array()) { return $this->call('listeattribute', array($node_guid, $knoten_typ, $attribute, $reihenfolge, $eingrenzung, $parameter)); } /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function listezahl($node_guid, $knoten_typ, $eingrenzung = false, array $parameter = array()) { return $this->call('listezahl', array($node_guid, $knoten_typ, $eingrenzung, $parameter)); } /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function moegliche($node_guid, $knoten_typ, $reihenfolge = false, $eingrenzung = false, array $parameter = array()) { return $this->call('moegliche', array($node_guid, $knoten_typ, $reihenfolge, $eingrenzung, $parameter)); } /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function moeglicheattribute($node_guid, $knoten_typ, $attribute, $reihenfolge = false, $eingrenzung = false, array $parameter = array()) { return $this->call('moeglicheattribute', array($node_guid, $knoten_typ, $attribute, $reihenfolge, $eingrenzung, $parameter)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function moeglichezahl($node_guid, $knoten_typ, $eingrenzung = false, array $parameter = array()) { return $this->call('moeglichezahl', array($node_guid, $knoten_typ, $eingrenzung, $parameter)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function alle($knoten_typ, $reihenfolge = false, $eingrenzung = false, array $parameter = array()) { return $this->call('alle', array($knoten_typ, $reihenfolge, $eingrenzung, $parameter)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function alleattribute($knoten_typ, $attribute, $reihenfolge = false, $eingrenzung = false, array $parameter = array()) { return $this->call('alleattribute', array($knoten_typ, $attribute, $reihenfolge, $eingrenzung, $parameter)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function allezahl($knoten_typ, $eingrenzung = false, array $parameter = array()) { return $this->call('allezahl', array($knoten_typ, $eingrenzung, $parameter)); } - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function aktion($node_guid, $aktionfunktion_name) { return $this->call('aktion', array($node_guid, $aktionfunktion_name)); } - /** */ - public function erzeugeknoten($knoten_typ) - { - return $this->call('erzeugeknoten', array($knoten_typ)); - } - - /** */ - public function vernichteknoten($node_guid) - { - return $this->call('vernichteknoten', array($node_guid)); - } - - /** */ + /** @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ public function service($graphmodulservice_name, ...$parameter) { return $this->call('service', func_get_args()); @@ -179,5 +171,4 @@ abstract class RemoteConnection implements ConnectionInterface { return $this->call('sessionsetze', [$schluessel, $wert]); } - /* */ } -- 2.34.1