From da19d9e9fae232f026a1e15a608a835b75566af0 Mon Sep 17 00:00:00 2001 From: Jan Trejbal Date: Mon, 27 Dec 2021 23:33:20 +0100 Subject: [PATCH] Fix PhpStan issues (#26) --- src/Entity/AEntity.php | 3 + src/Entity/Entries.php | 2 +- src/Group/Lists.php | 20 +++---- src/Group/Root.php | 2 +- src/Request.php | 116 +++++++++++++++++++++++++++++--------- tests/config/phpstan.neon | 7 +-- 6 files changed, 107 insertions(+), 43 deletions(-) diff --git a/src/Entity/AEntity.php b/src/Entity/AEntity.php index 6aed0d9..9367f17 100644 --- a/src/Entity/AEntity.php +++ b/src/Entity/AEntity.php @@ -12,6 +12,9 @@ abstract class AEntity */ protected $readOnly = []; + /** + * @var array|class-string> + */ protected $associations = []; /** diff --git a/src/Entity/Entries.php b/src/Entity/Entries.php index e064db3..e88b96b 100644 --- a/src/Entity/Entries.php +++ b/src/Entity/Entries.php @@ -8,7 +8,7 @@ final class Entries extends Schematic\Entries { /** - * @return Schematic\Entry[] + * @return array */ public function toArray() : array { diff --git a/src/Group/Lists.php b/src/Group/Lists.php index 560fb28..8dbb261 100644 --- a/src/Group/Lists.php +++ b/src/Group/Lists.php @@ -40,7 +40,7 @@ public function __construct(Request $apiRequest) */ public function getAll(?PaginationOption $paginationOption = null) : EntityLists { - return $this->apiRequest->get($this->getEndpointPath(), EntityLists::class, $paginationOption); + return $this->apiRequest->getTyped($this->getEndpointPath(), EntityLists::class, $paginationOption); } public function getAllIterator(string $listId) : \Generator @@ -75,7 +75,7 @@ public function getAllIterator(string $listId) : \Generator public function get(string $listId) : ListItem { try { - return $this->apiRequest->get($this->getListEndpointPath($listId), ListItem::class); + return $this->apiRequest->getTyped($this->getListEndpointPath($listId), ListItem::class); } catch (ClientException $clientException) { throw new ListNotFoundException("List '{$listId}' not found", $clientException); } @@ -88,7 +88,7 @@ public function get(string $listId) : ListItem public function getMembers(string $listId, ?PaginationOption $paginationOption = null) : EntityMemberLists { try { - return $this->apiRequest->get($this->getMemberEndpointPath($listId), EntityMemberLists::class, $paginationOption); + return $this->apiRequest->getTyped($this->getMemberEndpointPath($listId), EntityMemberLists::class, $paginationOption); } catch (ClientException $clientException) { throw new ListNotFoundException("List '{$listId}' not found", $clientException); } @@ -126,7 +126,7 @@ public function getMembersIterator(string $listId) : \Generator public function getMember(string $listId, string $memberHash) : MemberItem { try { - return $this->apiRequest->get($this->getOneMemberEndpointPath($listId, $memberHash), MemberItem::class); + return $this->apiRequest->getTyped($this->getOneMemberEndpointPath($listId, $memberHash), MemberItem::class); } catch (ClientException $clientException) { throw new MemberNotFoundException("Member '{$memberHash}' not found in the list '{$listId}'", $clientException); } @@ -139,7 +139,7 @@ public function getMember(string $listId, string $memberHash) : MemberItem public function addMember(MemberItem $memberItem) : MemberItem { try { - return $this->apiRequest->put( + return $this->apiRequest->putTyped( $this->getOneMemberEndpointPath( $memberItem->list_id, $memberItem->id @@ -159,7 +159,7 @@ public function addMember(MemberItem $memberItem) : MemberItem public function updateMember(MemberItem $memberItem) : MemberItem { try { - return $this->apiRequest->patch( + return $this->apiRequest->patchTyped( $this->getOneMemberEndpointPath( $memberItem->list_id, $memberItem->id @@ -219,7 +219,7 @@ public function removePermanentMember(MemberItem $memberItem) : ?array public function getSegments(string $listId, ?PaginationOption $paginationOption = null) : EntitySegmentLists { try { - return $this->apiRequest->get($this->getSegmentEndpointPath($listId), EntitySegmentLists::class, $paginationOption); + return $this->apiRequest->getTyped($this->getSegmentEndpointPath($listId), EntitySegmentLists::class, $paginationOption); } catch (ClientException $clientException) { throw new ListNotFoundException("List '{$listId}' not found", $clientException); } @@ -257,7 +257,7 @@ public function getSegmentsIterator(string $listId) : \Generator public function getSegment(string $listId, int $segmentId) : Segment { try { - return $this->apiRequest->get($this->getOneSegmentEndpointPath($listId, $segmentId), Segment::class); + return $this->apiRequest->getTyped($this->getOneSegmentEndpointPath($listId, $segmentId), Segment::class); } catch (ClientException $clientException) { throw new ListNotFoundException("Segment '{$segmentId}' not found in the list '{$listId}'", $clientException); } @@ -275,7 +275,7 @@ public function addSegment(string $listId, string $segmentName) : Segment } try { - return $this->apiRequest->post( + return $this->apiRequest->postTyped( $this->getSegmentEndpointPath($listId), [ 'name' => $segmentName, @@ -295,7 +295,7 @@ public function addSegment(string $listId, string $segmentName) : Segment public function addSegmentMember(int $segmentId, MemberItem $memberItem) : MemberItem { try { - return $this->apiRequest->post( + return $this->apiRequest->postTyped( $this->getOneSegmentEndpointPath($memberItem->list_id, $segmentId) . self::GROUP_MEMBER_PREFIX, [ 'email_address' => $memberItem->email_address, diff --git a/src/Group/Root.php b/src/Group/Root.php index 93f4f9a..aa84762 100644 --- a/src/Group/Root.php +++ b/src/Group/Root.php @@ -24,6 +24,6 @@ public function __construct(Request $apiRequest) */ public function get() : EntityRoot { - return $this->apiRequest->get('/', EntityRoot::class); + return $this->apiRequest->getTyped('/', EntityRoot::class); } } diff --git a/src/Request.php b/src/Request.php index 5ae5757..f2d782f 100644 --- a/src/Request.php +++ b/src/Request.php @@ -4,10 +4,10 @@ namespace Trejjam\MailChimp; use GuzzleHttp\Client; +use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\RequestOptions; use Nette\Utils\Json; use Nette\Utils\JsonException; -use Schematic\Entry; use Trejjam\MailChimp\Exception\RequestException; final class Request @@ -32,74 +32,121 @@ public function __construct( Client $httpClient, string $apiUrl, string $apiKey - ) { + ) + { $this->httpClient = $httpClient; $this->apiUrl = $apiUrl; $this->apiKey = $apiKey; } /** - * @return array|Entry|mixed + * @template T + * @param class-string $endpointClass + * @return T + * @throws JsonException + * @throws RequestException + * @throws GuzzleException + */ + public function getTyped(string $endpointPath, string $endpointClass, ?PaginationOption $paginationOption = null) + { + return $this->makeTypedRequest(__FUNCTION__, $endpointPath, $endpointClass, [], $paginationOption); + } + + /** + * @template T + * @param class-string $endpointClass + * @return T * @throws JsonException + * @throws RequestException + * @throws GuzzleException */ - public function get(string $endpointPath, ?string $endpointClass = null, ?PaginationOption $paginationOption = null) + public function putTyped(string $endpointPath, array $body, string $endpointClass) { - return $this->makeRequest(__FUNCTION__, $endpointPath, $endpointClass, [], $paginationOption); + return $this->makeTypedRequest(__FUNCTION__, $endpointPath, $endpointClass, [ + RequestOptions::BODY => Json::encode($body), + ]); } /** - * @return array|mixed|Entry + * @template T + * @param class-string $endpointClass + * @return T * @throws JsonException + * @throws RequestException + * @throws GuzzleException */ - public function put(string $endpointPath, array $body, ?string $endpointClass = null) + public function patchTyped(string $endpointPath, array $body, string $endpointClass) { - return $this->makeRequest(__FUNCTION__, $endpointPath, $endpointClass, [ + return $this->makeTypedRequest(__FUNCTION__, $endpointPath, $endpointClass, [ RequestOptions::BODY => Json::encode($body), ]); } /** - * @return array|mixed|Entry + * @return array * @throws JsonException + * @throws RequestException + * @throws GuzzleException */ - public function patch(string $endpointPath, array $body, ?string $endpointClass = null) + public function post(string $endpointPath, array $body) { - return $this->makeRequest(__FUNCTION__, $endpointPath, $endpointClass, [ + return $this->makeRequest(__FUNCTION__, $endpointPath, [ RequestOptions::BODY => Json::encode($body), ]); } /** - * @return array|mixed|Entry + * @template T + * @param class-string $endpointClass + * @return T * @throws JsonException + * @throws RequestException + * @throws GuzzleException */ - public function post(string $endpointPath, array $body, ?string $endpointClass = null) + public function postTyped(string $endpointPath, array $body, string $endpointClass) { - return $this->makeRequest(__FUNCTION__, $endpointPath, $endpointClass, [ + return $this->makeTypedRequest(__FUNCTION__, $endpointPath, $endpointClass, [ RequestOptions::BODY => Json::encode($body), ]); } /** - * @return array|Entry|mixed + * @return array * @throws JsonException + * @throws RequestException + * @throws GuzzleException */ - public function delete(string $endpointPath, ?string $endpointClass = null) + public function delete(string $endpointPath) { - return $this->makeRequest(__FUNCTION__, $endpointPath, $endpointClass); + return $this->makeRequest(__FUNCTION__, $endpointPath); } /** - * @return array|Entry|mixed + * @template T + * @param class-string $endpointClass + * @return T * @throws JsonException + * @throws RequestException + * @throws GuzzleException + */ + public function deleteTyped(string $endpointPath, string $endpointClass) + { + return $this->makeTypedRequest(__FUNCTION__, $endpointPath, $endpointClass); + } + + /** + * @return array + * @throws JsonException + * @throws RequestException + * @throws GuzzleException */ private function makeRequest( - string $method, - string $endpointPath, - ?string $endpointClass = null, - array $requestOptions = [], + string $method, + string $endpointPath, + array $requestOptions = [], ?PaginationOption $paginationOption = null - ) { + ) + { $mergedRequestOptions = array_merge_recursive( [ RequestOptions::AUTH => [self::API_USER, $this->apiKey], @@ -124,11 +171,26 @@ private function makeRequest( ))->setResponse($response); } - $returnArray = Json::decode($response->getBody()->getContents(), Json::FORCE_ARRAY); + return (array)Json::decode($response->getBody()->getContents(), Json::FORCE_ARRAY); + } - if ($endpointClass === null || $endpointClass === '') { - return $returnArray; - } + /** + * @template T + * @param class-string $endpointClass + * @return T + * @throws JsonException + * @throws RequestException + * @throws GuzzleException + */ + private function makeTypedRequest( + string $method, + string $endpointPath, + string $endpointClass, + array $requestOptions = [], + ?PaginationOption $paginationOption = null + ) + { + $returnArray = $this->makeRequest($method, $endpointPath, $requestOptions, $paginationOption); return new $endpointClass($returnArray); } diff --git a/tests/config/phpstan.neon b/tests/config/phpstan.neon index 8b91961..8bd698a 100644 --- a/tests/config/phpstan.neon +++ b/tests/config/phpstan.neon @@ -2,15 +2,14 @@ parameters: checkMissingIterableValueType: false treatPhpDocTypesAsCertain: false ignoreErrors: - - '~^Property Trejjam\\MailChimp\\Entity\\[a-zA-Z\\]+::\$[a-z]+ has no typehint specified\.$~' - - message: '~^Method Trejjam\\MailChimp\\Entity\\AEntity::__set\(\) has parameter \$value with no typehint specified\.$~' + message: '~^Method Trejjam\\MailChimp\\Entity\\AEntity::__set\(\) has parameter \$value with no type specified\.$~' path: %currentWorkingDirectory%/src/Entity/AEntity.php - - message: '~^Method Trejjam\\MailChimp\\Entity\\AEntity::__get\(\) has no return typehint specified\.$~' + message: '~^Method Trejjam\\MailChimp\\Entity\\AEntity::__get\(\) has no return type specified\.$~' path: %currentWorkingDirectory%/src/Entity/AEntity.php - - message: '~^Method Trejjam\\MailChimp\\Entity\\Entries::toArray\(\) should return array but returns array\.$~' + message: '~^Method Trejjam\\MailChimp\\Entity\\Entries::toArray\(\) should return array but returns array\.$~' path: %currentWorkingDirectory%/src/Entity/Entries.php earlyTerminatingMethodCalls: