From 7356d5b3ba196b8c55587040247af049dbbb2142 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 26 Jul 2022 09:43:07 -0700 Subject: [PATCH 1/4] chore: drop support for PHP 5.6 --- .github/sync-repo-settings.yaml | 5 ++--- .github/workflows/tests.yml | 6 +++--- composer.json | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index f34fa21d5..3e7749fa6 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -5,16 +5,15 @@ branchProtectionRules: - pattern: main isAdminEnforced: true requiredStatusCheckContexts: - - 'PHP 5.6 Unit Test' - - 'PHP 5.6 Unit Test protobuf-3.12.2,grpc' + - 'PHP 7.0 Unit Test protobuf-3.12.2,grpc' - 'PHP 7.0 Unit Test' - 'PHP 7.1 Unit Test' - 'PHP 7.2 Unit Test' - 'PHP 7.3 Unit Test' - - 'PHP 7.3 Unit Test protobuf-3.12.2,grpc' - 'PHP 7.4 Unit Test' - 'PHP 8.0 Unit Test' - 'PHP 8.1 Unit Test' + - 'PHP 8.1 Unit Test protobuf-3.12.2,grpc' - 'Composer Conflict Test' - 'PHP Style Check' - 'cla/google' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 75c8be6fd..109e3b5a7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,14 +9,14 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php: [ 5.6, "7.0", 7.1, 7.2, 7.3, 7.4, "8.0", 8.1 ] + php: [ "7.0", 7.1, 7.2, 7.3, 7.4, "8.0", 8.1 ] extensions: [""] tools: [""] include: - - php: 5.6 + - php: "7.0" extensions: "protobuf-3.12.2,grpc" tools: "pecl" - - php: 7.3 + - php: 8.1 extensions: "protobuf-3.12.2,grpc" tools: "pecl" name: "PHP ${{ matrix.php }} Unit Test ${{ matrix.extensions }}" diff --git a/composer.json b/composer.json index faca76f59..4bcdf6a36 100644 --- a/composer.json +++ b/composer.json @@ -6,11 +6,11 @@ "homepage": "https://github.com/googleapis/gax-php", "license": "BSD-3-Clause", "require": { - "php": ">=5.6", + "php": ">=7.0", "google/auth": "^1.18.0", "google/grpc-gcp": "^0.2", "grpc/grpc": "^1.13", - "google/protobuf": "^3.12.2", + "google/protobuf": "^3.21.4", "guzzlehttp/promises": "^1.3", "guzzlehttp/psr7": "^1.7.0||^2", "google/common-protos": "^1.0||^2.0||^3.0", From 5a7694ef4f6520d41d593c6264d4264431c7a7f7 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Fri, 22 Jul 2022 12:59:45 -0700 Subject: [PATCH 2/4] chore: add parameter typehints and improve phpdoc --- src/AgentHeader.php | 4 +-- src/ApiException.php | 23 ++++++++----- src/ApiStatus.php | 8 ++--- src/ArrayTrait.php | 6 ++-- src/BidiStream.php | 7 ++-- src/Call.php | 8 ++--- src/ClientStream.php | 7 ++-- src/CredentialsWrapper.php | 10 ++++-- src/FixedSizeCollection.php | 8 ++--- src/GapicClientTrait.php | 32 +++++++++---------- src/Middleware/FixedHeaderMiddleware.php | 7 ++-- src/Middleware/RetryMiddleware.php | 2 +- src/OperationResponse.php | 4 +-- src/Page.php | 2 +- src/PageStreamingDescriptor.php | 10 +++--- src/PagedListResponse.php | 4 +-- src/PathTemplate.php | 6 ++-- src/PollingTrait.php | 2 +- src/RequestBuilder.php | 18 +++++------ src/RequestParamsHeaderDescriptor.php | 2 +- .../AbsoluteResourceTemplate.php | 12 +++---- src/ResourceTemplate/Parser.php | 16 +++++----- .../RelativeResourceTemplate.php | 17 ++++++---- .../ResourceTemplateInterface.php | 4 +-- src/ResourceTemplate/Segment.php | 20 ++++++------ src/RetrySettings.php | 10 +++--- src/Serializer.php | 24 +++++++------- src/ServerStream.php | 1 + src/ServiceAddressTrait.php | 2 +- src/Testing/GeneratedTest.php | 7 ++++ src/Testing/MockBidiStreamingCall.php | 11 ++++--- src/Testing/MockClientStreamingCall.php | 11 ++++--- src/Testing/MockGrpcTransport.php | 30 +++++++++++++++-- src/Testing/MockServerStreamingCall.php | 11 ++++--- src/Testing/MockStatus.php | 10 ++++-- src/Testing/MockStubTrait.php | 6 ++-- src/Testing/MockTransport.php | 2 +- src/Testing/MockUnaryCall.php | 10 +++--- src/Testing/SerializationTrait.php | 4 +++ src/Transport/Grpc/ForwardingCall.php | 4 ++- .../Grpc/ServerStreamingCallWrapper.php | 3 ++ src/Transport/GrpcFallbackTransport.php | 4 +-- src/Transport/GrpcTransport.php | 4 +-- src/Transport/Rest/JsonStreamDecoder.php | 2 +- .../Rest/RestServerStreamingCall.php | 6 ++-- src/Transport/RestTransport.php | 2 +- src/ValidationTrait.php | 6 ++-- src/Version.php | 2 +- tests/Tests/Unit/GapicClientTraitTest.php | 3 +- tests/Tests/Unit/PageTest.php | 2 +- tests/Tests/Unit/PagedListResponseTest.php | 2 +- .../Unit/ResourceTemplate/ParserTest.php | 3 -- 52 files changed, 245 insertions(+), 176 deletions(-) diff --git a/src/AgentHeader.php b/src/AgentHeader.php index bff34a4d6..b7906afd2 100644 --- a/src/AgentHeader.php +++ b/src/AgentHeader.php @@ -59,7 +59,7 @@ class AgentHeader * } * @return array Agent header array */ - public static function buildAgentHeader($headerInfo) + public static function buildAgentHeader(array $headerInfo) { $metricsHeaders = []; @@ -138,7 +138,7 @@ public static function buildAgentHeader($headerInfo) * @return string the gapic version * @throws \ReflectionException */ - public static function readGapicVersionFromFile($callingClass) + public static function readGapicVersionFromFile(string $callingClass) { $callingClassFile = (new \ReflectionClass($callingClass))->getFileName(); $versionFile = substr( diff --git a/src/ApiException.php b/src/ApiException.php index fe2e0b543..3e8b03b59 100644 --- a/src/ApiException.php +++ b/src/ApiException.php @@ -35,6 +35,8 @@ use Google\Protobuf\Internal\RepeatedField; use Google\Rpc\Status; use GuzzleHttp\Exception\RequestException; +use Google\ApiCore\Testing\MockStatus; +use stdClass; /** * Represents an exception thrown during an RPC. @@ -58,9 +60,9 @@ class ApiException extends Exception * } */ public function __construct( - $message, - $code, - $status, + string $message, + int $code, + string $status = null, array $optionalArgs = [] ) { $optionalArgs += [ @@ -137,10 +139,10 @@ public function getErrorInfoMetadata() } /** - * @param \stdClass $status + * @param stdClass $status * @return ApiException */ - public static function createFromStdClass($status) + public static function createFromStdClass(stdClass $status) { $metadata = property_exists($status, 'metadata') ? $status->metadata : null; return self::create( @@ -237,8 +239,13 @@ private static function containsErrorInfo(array $decodedMetadata) * @param Exception|null $previous * @return ApiException */ - private static function create($basicMessage, $rpcCode, $metadata, array $decodedMetadata, $previous = null) - { + private static function create( + string $basicMessage, + int $rpcCode, + $metadata = null, + array $decodedMetadata = null, + Exception $previous = null + ) { $containsErrorInfo = self::containsErrorInfo($decodedMetadata); $rpcStatus = ApiStatus::statusFromRpcCode($rpcCode); $messageData = [ @@ -286,7 +293,7 @@ public static function createFromRpcStatus(Status $status) * @return ApiException * @throws ValidationException */ - public static function createFromRequestException(RequestException $ex, $isStream = false) + public static function createFromRequestException(RequestException $ex, bool $isStream = false) { $res = $ex->getResponse(); $body = (string) $res->getBody(); diff --git a/src/ApiStatus.php b/src/ApiStatus.php index ea8e17b44..aa6adcfc1 100644 --- a/src/ApiStatus.php +++ b/src/ApiStatus.php @@ -112,7 +112,7 @@ class ApiStatus * @param string $status * @return bool */ - public static function isValidStatus($status) + public static function isValidStatus(string $status) { return array_key_exists($status, self::$apiStatusToCodeMap); } @@ -121,7 +121,7 @@ public static function isValidStatus($status) * @param int $code * @return string */ - public static function statusFromRpcCode($code) + public static function statusFromRpcCode(int $code) { if (array_key_exists($code, self::$codeToApiStatusMap)) { return self::$codeToApiStatusMap[$code]; @@ -133,7 +133,7 @@ public static function statusFromRpcCode($code) * @param string $status * @return int */ - public static function rpcCodeFromStatus($status) + public static function rpcCodeFromStatus(string $status) { if (array_key_exists($status, self::$apiStatusToCodeMap)) { return self::$apiStatusToCodeMap[$status]; @@ -148,7 +148,7 @@ public static function rpcCodeFromStatus($status) * @param int $httpStatusCode * @return int */ - public static function rpcCodeFromHttpStatusCode($httpStatusCode) + public static function rpcCodeFromHttpStatusCode(int $httpStatusCode) { if (array_key_exists($httpStatusCode, self::$httpStatusCodeToRpcCodeMap)) { return self::$httpStatusCodeToRpcCodeMap[$httpStatusCode]; diff --git a/src/ArrayTrait.php b/src/ArrayTrait.php index c79e1fda7..8948800a5 100644 --- a/src/ArrayTrait.php +++ b/src/ArrayTrait.php @@ -46,7 +46,7 @@ trait ArrayTrait * @return mixed|null * @throws \InvalidArgumentException */ - private function pluck($key, array &$arr, $isRequired = true) + private function pluck(string $key, array &$arr, bool $isRequired = true) { if (!array_key_exists($key, $arr)) { if ($isRequired) { @@ -70,7 +70,7 @@ private function pluck($key, array &$arr, $isRequired = true) * @param array $arr * @return array */ - private function pluckArray(array $keys, &$arr) + private function pluckArray(array $keys, array &$arr) { $values = []; @@ -118,7 +118,7 @@ private function arrayFilterRemoveNull(array $arr) * @param array $arr * @return array */ - private function subsetArray(array $keys, $arr) + private function subsetArray(array $keys, array $arr) { return array_intersect_key( $arr, diff --git a/src/BidiStream.php b/src/BidiStream.php index 472486467..d62338fd7 100644 --- a/src/BidiStream.php +++ b/src/BidiStream.php @@ -32,6 +32,7 @@ namespace Google\ApiCore; use Google\Rpc\Code; +use Grpc\BidiStreamingCall; /** * BidiStream is the response object from a gRPC bidirectional streaming API call. @@ -47,10 +48,10 @@ class BidiStream /** * BidiStream constructor. * - * @param \Grpc\BidiStreamingCall $bidiStreamingCall The gRPC bidirectional streaming call object + * @param BidiStreamingCall $bidiStreamingCall The gRPC bidirectional streaming call object * @param array $streamingDescriptor */ - public function __construct($bidiStreamingCall, array $streamingDescriptor = []) + public function __construct(BidiStreamingCall $bidiStreamingCall, array $streamingDescriptor = []) { $this->call = $bidiStreamingCall; if (array_key_exists('resourcesGetMethod', $streamingDescriptor)) { @@ -82,7 +83,7 @@ public function write($request) * * @throws ValidationException */ - public function writeAll($requests = []) + public function writeAll(array $requests = []) { foreach ($requests as $request) { $this->write($request); diff --git a/src/Call.php b/src/Call.php index 7a94ae017..9198ade8b 100644 --- a/src/Call.php +++ b/src/Call.php @@ -54,15 +54,15 @@ class Call * @param string $method * @param string $decodeType * @param mixed|Message $message - * @param array $descriptor + * @param array|null $descriptor * @param int $callType */ public function __construct( - $method, - $decodeType, + string $method, + string $decodeType = null, $message = null, $descriptor = [], - $callType = Call::UNARY_CALL + int $callType = Call::UNARY_CALL ) { $this->method = $method; $this->decodeType = $decodeType; diff --git a/src/ClientStream.php b/src/ClientStream.php index 76d79e893..cdaaaf0a8 100644 --- a/src/ClientStream.php +++ b/src/ClientStream.php @@ -32,6 +32,7 @@ namespace Google\ApiCore; use Google\Rpc\Code; +use Grpc\ClientStreamingCall; /** * ClientStream is the response object from a gRPC client streaming API call. @@ -43,11 +44,11 @@ class ClientStream /** * ClientStream constructor. * - * @param \Grpc\ClientStreamingCall $clientStreamingCall The gRPC client streaming call object + * @param ClientStreamingCall $clientStreamingCall The gRPC client streaming call object * @param array $streamingDescriptor */ public function __construct( // @phpstan-ignore-line - $clientStreamingCall, + ClientStreamingCall $clientStreamingCall, array $streamingDescriptor = [] ) { $this->call = $clientStreamingCall; @@ -86,7 +87,7 @@ public function readResponse() * @param mixed[] $requests An iterator of request objects to write to the server * @return mixed The response object from the server */ - public function writeAllAndReadResponse($requests) + public function writeAllAndReadResponse(array $requests) { foreach ($requests as $request) { $this->write($request); diff --git a/src/CredentialsWrapper.php b/src/CredentialsWrapper.php index 63307f30d..831e3e2bc 100644 --- a/src/CredentialsWrapper.php +++ b/src/CredentialsWrapper.php @@ -193,7 +193,7 @@ public function getBearerString() * @param string $audience optional audience for self-signed JWTs. * @return callable Callable function that returns an authorization header. */ - public function getAuthorizationHeaderCallback($audience = null) + public function getAuthorizationHeaderCallback(string $audience = null) { $credentialsFetcher = $this->credentialsFetcher; $authHttpHandler = $this->authHttpHandler; @@ -269,7 +269,7 @@ private static function buildApplicationDefaultCredentials( } } - private static function getToken(FetchAuthTokenInterface $credentialsFetcher, $authHttpHandler) + private static function getToken(FetchAuthTokenInterface $credentialsFetcher, callable $authHttpHandler) { $token = $credentialsFetcher->getLastReceivedToken(); if (self::isExpired($token)) { @@ -281,12 +281,18 @@ private static function getToken(FetchAuthTokenInterface $credentialsFetcher, $a return $token['access_token']; } + /** + * @param mixed $token + */ private static function isValid($token) { return is_array($token) && array_key_exists('access_token', $token); } + /** + * @param mixed $token + */ private static function isExpired($token) { return !(self::isValid($token) diff --git a/src/FixedSizeCollection.php b/src/FixedSizeCollection.php index f9cbcc529..eecd74408 100644 --- a/src/FixedSizeCollection.php +++ b/src/FixedSizeCollection.php @@ -50,9 +50,9 @@ class FixedSizeCollection implements IteratorAggregate /** * FixedSizeCollection constructor. * @param Page $initialPage - * @param integer $collectionSize + * @param int $collectionSize */ - public function __construct($initialPage, $collectionSize) + public function __construct(Page $initialPage, int $collectionSize) { if ($collectionSize <= 0) { throw new InvalidArgumentException( @@ -165,10 +165,10 @@ private function getLastPage() /** * @param Page $initialPage - * @param integer $collectionSize + * @param int $collectionSize * @return Page[] */ - private static function createPageArray($initialPage, $collectionSize) + private static function createPageArray(Page $initialPage, int $collectionSize) { $pageList = [$initialPage]; $currentPage = $initialPage; diff --git a/src/GapicClientTrait.php b/src/GapicClientTrait.php index 0af55d96c..827a061e8 100644 --- a/src/GapicClientTrait.php +++ b/src/GapicClientTrait.php @@ -126,7 +126,7 @@ private static function getGapicVersion(array $options) } } - private static function initGrpcGcpConfig($hostName, $confPath) + private static function initGrpcGcpConfig(string $hostName, string $confPath) { $apiConfig = new ApiConfig(); $apiConfig->mergeFromJsonString(file_get_contents($confPath)); @@ -253,7 +253,7 @@ private function buildClientOptions(array $options) return $options; } - private function shouldUseMtlsEndpoint($options) + private function shouldUseMtlsEndpoint(array $options) { $mtlsEndpointEnvVar = getenv('GOOGLE_API_USE_MTLS_ENDPOINT'); if ('always' === $mtlsEndpointEnvVar) { @@ -266,7 +266,7 @@ private function shouldUseMtlsEndpoint($options) return !empty($options['clientCertSource']); } - private static function determineMtlsEndpoint($apiEndpoint) + private static function determineMtlsEndpoint(string $apiEndpoint) { $parts = explode('.', $apiEndpoint); if (count($parts) < 3) { @@ -449,7 +449,7 @@ private function createCredentialsWrapper($credentials, array $credentialsConfig * @throws ValidationException */ private function createTransport( - $apiEndpoint, + string $apiEndpoint, $transport, array $transportConfig, callable $clientCertSource = null @@ -545,12 +545,12 @@ private static function defaultTransport() * @return PromiseInterface|BidiStream|ClientStream|ServerStream */ private function startCall( - $methodName, - $decodeType, + string $methodName, + string $decodeType, array $optionalArgs = [], Message $request = null, - $callType = Call::UNARY_CALL, - $interfaceName = null + int $callType = Call::UNARY_CALL, + string $interfaceName = null ) { $callStack = $this->createCallStack( $this->configureCallConstructionOptions($methodName, $optionalArgs) @@ -631,7 +631,7 @@ private function createCallStack(array $callConstructionOptions) * * @return array */ - private function configureCallConstructionOptions($methodName, array $optionalArgs) + private function configureCallConstructionOptions(string $methodName, array $optionalArgs) { $retrySettings = $this->retrySettings[$methodName]; // Allow for retry settings to be changed at call time @@ -667,12 +667,12 @@ private function configureCallConstructionOptions($methodName, array $optionalAr * @return PromiseInterface */ private function startOperationsCall( - $methodName, + string $methodName, array $optionalArgs, Message $request, $client, - $interfaceName = null, - $operationClass = null + string $interfaceName = null, + string $operationClass = null ) { $callStack = $this->createCallStack( $this->configureCallConstructionOptions($methodName, $optionalArgs) @@ -717,11 +717,11 @@ private function startOperationsCall( * @return PagedListResponse */ private function getPagedListResponse( - $methodName, + string $methodName, array $optionalArgs, - $decodeType, + string $decodeType, Message $request, - $interfaceName = null + string $interfaceName = null ) { $callStack = $this->createCallStack( $this->configureCallConstructionOptions($methodName, $optionalArgs) @@ -751,7 +751,7 @@ private function getPagedListResponse( * * @return string */ - private function buildMethod($interfaceName, $methodName) + private function buildMethod(string $interfaceName = null, string $methodName = null) { return sprintf( '%s/%s', diff --git a/src/Middleware/FixedHeaderMiddleware.php b/src/Middleware/FixedHeaderMiddleware.php index 4734286d0..14206c1e8 100644 --- a/src/Middleware/FixedHeaderMiddleware.php +++ b/src/Middleware/FixedHeaderMiddleware.php @@ -45,8 +45,11 @@ class FixedHeaderMiddleware private $headers; private $overrideUserHeaders; - public function __construct(callable $nextHandler, array $headers, $overrideUserHeaders = false) - { + public function __construct( + callable $nextHandler, + array $headers, + bool $overrideUserHeaders = false + ) { $this->nextHandler = $nextHandler; $this->headers = $headers; $this->overrideUserHeaders = $overrideUserHeaders; diff --git a/src/Middleware/RetryMiddleware.php b/src/Middleware/RetryMiddleware.php index 934b5df07..5991a7e5c 100644 --- a/src/Middleware/RetryMiddleware.php +++ b/src/Middleware/RetryMiddleware.php @@ -106,7 +106,7 @@ public function __invoke(Call $call, array $options) * @return PromiseInterface * @throws ApiException */ - private function retry(Call $call, array $options, $status) + private function retry(Call $call, array $options, string $status) { $delayMult = $this->retrySettings->getRetryDelayMultiplier(); $maxDelayMs = $this->retrySettings->getMaxRetryDelayMillis(); diff --git a/src/OperationResponse.php b/src/OperationResponse.php index 139520c87..b6a734de4 100644 --- a/src/OperationResponse.php +++ b/src/OperationResponse.php @@ -110,7 +110,7 @@ class OperationResponse * @type string $operationErrorMessageMethod The method on the operation to get the error status * } */ - public function __construct($operationName, $operationsClient, $options = []) + public function __construct(string $operationName, $operationsClient, array $options = []) { $this->operationName = $operationName; $this->operationsClient = $operationsClient; @@ -234,7 +234,7 @@ public function getName() * @throws ValidationException * @return bool Indicates if the operation completed. */ - public function pollUntilComplete($options = []) + public function pollUntilComplete(array $options = []) { if ($this->isDone()) { return true; diff --git a/src/Page.php b/src/Page.php index 89fef1b02..fded0dcca 100644 --- a/src/Page.php +++ b/src/Page.php @@ -110,7 +110,7 @@ public function getNextPageToken() * @throws ApiException if the call to fetch the next page fails. * @return Page */ - public function getNextPage($pageSize = null) + public function getNextPage(int $pageSize = null) { if (!$this->hasNextPage()) { throw new ValidationException( diff --git a/src/PageStreamingDescriptor.php b/src/PageStreamingDescriptor.php index d7fef50fb..351eaf7fc 100644 --- a/src/PageStreamingDescriptor.php +++ b/src/PageStreamingDescriptor.php @@ -52,7 +52,7 @@ class PageStreamingDescriptor * @type string $requestPageSizeGetMethod the get method for the page size in the request object. * } */ - public function __construct($descriptor) + public function __construct(array $descriptor) { self::validate($descriptor); $this->descriptor = $descriptor; @@ -71,7 +71,7 @@ public function __construct($descriptor) * } * @return PageStreamingDescriptor */ - public static function createFromFields($fields) + public static function createFromFields(array $fields) { $requestPageToken = $fields['requestPageTokenField']; $responsePageToken = $fields['responsePageTokenField']; @@ -93,12 +93,12 @@ public static function createFromFields($fields) return new PageStreamingDescriptor($descriptor); } - private static function getMethod($field) + private static function getMethod(string $field) { return 'get' . ucfirst($field); } - private static function setMethod($field) + private static function setMethod(string $field) { return 'set' . ucfirst($field); } @@ -159,7 +159,7 @@ public function getRequestPageSizeSetMethod() return $this->descriptor['requestPageSizeSetMethod']; } - private static function validate($descriptor) + private static function validate(array $descriptor) { $requiredFields = [ 'requestPageTokenGetMethod', diff --git a/src/PagedListResponse.php b/src/PagedListResponse.php index 45691be7f..62e6511ee 100644 --- a/src/PagedListResponse.php +++ b/src/PagedListResponse.php @@ -168,7 +168,7 @@ public function iteratePages() * @throws ValidationException if a FixedSizeCollection of the specified size cannot be constructed * @return FixedSizeCollection */ - public function expandToFixedSizeCollection($collectionSize) + public function expandToFixedSizeCollection(int $collectionSize) { return $this->getPage()->expandToFixedSizeCollection($collectionSize); } @@ -190,7 +190,7 @@ public function expandToFixedSizeCollection($collectionSize) * @throws ValidationException if a FixedSizeCollection of the specified size cannot be constructed * @return Generator|FixedSizeCollection[] */ - public function iterateFixedSizeCollections($collectionSize) + public function iterateFixedSizeCollections(int $collectionSize) { return $this->expandToFixedSizeCollection($collectionSize)->iterateCollections(); } diff --git a/src/PathTemplate.php b/src/PathTemplate.php index 9374ef77e..b7cd5aa2e 100644 --- a/src/PathTemplate.php +++ b/src/PathTemplate.php @@ -54,7 +54,7 @@ class PathTemplate implements ResourceTemplateInterface * @param string $path A path template string * @throws ValidationException When $path cannot be parsed into a valid PathTemplate */ - public function __construct($path) + public function __construct(string $path = null) { if (empty($path)) { throw new ValidationException('Cannot construct PathTemplate from empty string'); @@ -94,7 +94,7 @@ public function render(array $bindings) * @param string $path A resource string. * @return bool */ - public function matches($path) + public function matches(string $path) { return $this->resourceTemplate->matches($path); } @@ -106,7 +106,7 @@ public function matches($path) * @throws ValidationException if path can't be matched to the template. * @return array Array matching var names to binding values. */ - public function match($path) + public function match(string $path) { return $this->resourceTemplate->match($path); } diff --git a/src/PollingTrait.php b/src/PollingTrait.php index dab1423d5..5f12f7916 100644 --- a/src/PollingTrait.php +++ b/src/PollingTrait.php @@ -87,7 +87,7 @@ protected function getCurrentTimeMillis() * * @param int $millis */ - protected function sleepMillis($millis) + protected function sleepMillis(int $millis) { usleep($millis * 1000); } diff --git a/src/RequestBuilder.php b/src/RequestBuilder.php index 8444d5907..ac2ec5ae5 100644 --- a/src/RequestBuilder.php +++ b/src/RequestBuilder.php @@ -58,7 +58,7 @@ class RequestBuilder * @param string $restConfigPath * @throws ValidationException */ - public function __construct($baseUri, $restConfigPath) + public function __construct(string $baseUri, string $restConfigPath) { self::validateFileExists($restConfigPath); $this->baseUri = $baseUri; @@ -69,7 +69,7 @@ public function __construct($baseUri, $restConfigPath) * @param string $path * @return bool */ - public function pathExists($path) + public function pathExists(string $path) { list($interface, $method) = explode('/', $path); return isset($this->restConfig['interfaces'][$interface][$method]); @@ -82,7 +82,7 @@ public function pathExists($path) * @return RequestInterface * @throws ValidationException */ - public function build($path, Message $message, array $headers = []) + public function build(string $path, Message $message, array $headers = []) { list($interface, $method) = explode('/', $path); @@ -108,12 +108,12 @@ public function build($path, Message $message, array $headers = []) // We found a valid uriTemplate - now build and return the Request list($body, $queryParams) = $this->constructBodyAndQueryParameters($message, $config); - + // Request enum fields will be encoded as numbers rather than strings (in the response). if ($numericEnums) { $queryParams['$alt'] = "json;enum-encoding=int"; } - + $uri = $this->buildUri($pathTemplate, $queryParams); return new Request( @@ -142,7 +142,7 @@ public function build($path, Message $message, array $headers = []) * @param array $config * @return array[] An array of configs */ - private function getConfigsForUriTemplates($config) + private function getConfigsForUriTemplates(array $config) { $configs = [$config]; @@ -160,7 +160,7 @@ private function getConfigsForUriTemplates($config) * @param array $config * @return array Tuple [$body, $queryParams] */ - private function constructBodyAndQueryParameters(Message $message, $config) + private function constructBodyAndQueryParameters(Message $message, array $config) { $messageDataJson = $message->serializeToJsonString(); @@ -241,7 +241,7 @@ function (Message $result = null, $getter) { * @return null|string * @throws ValidationException */ - private function tryRenderPathTemplate($uriTemplate, array $bindings) + private function tryRenderPathTemplate(string $uriTemplate, array $bindings) { $template = new AbsoluteResourceTemplate($uriTemplate); @@ -257,7 +257,7 @@ private function tryRenderPathTemplate($uriTemplate, array $bindings) * @param array $queryParams * @return UriInterface */ - private function buildUri($path, $queryParams) + private function buildUri(string $path, array $queryParams) { $uri = Utils::uriFor( sprintf( diff --git a/src/RequestParamsHeaderDescriptor.php b/src/RequestParamsHeaderDescriptor.php index 0be8a9cb6..73e9af331 100644 --- a/src/RequestParamsHeaderDescriptor.php +++ b/src/RequestParamsHeaderDescriptor.php @@ -50,7 +50,7 @@ class RequestParamsHeaderDescriptor * @param array $requestParams An associative array which contains request params header data in * a form ['field_name.subfield_name' => value]. */ - public function __construct($requestParams) + public function __construct(array $requestParams) { $headerKey = self::HEADER_KEY; diff --git a/src/ResourceTemplate/AbsoluteResourceTemplate.php b/src/ResourceTemplate/AbsoluteResourceTemplate.php index a5c70081c..2b37d472f 100644 --- a/src/ResourceTemplate/AbsoluteResourceTemplate.php +++ b/src/ResourceTemplate/AbsoluteResourceTemplate.php @@ -59,10 +59,10 @@ class AbsoluteResourceTemplate implements ResourceTemplateInterface /** * AbsoluteResourceTemplate constructor. - * @param string $path + * @param string|null $path * @throws ValidationException */ - public function __construct($path) + public function __construct(string $path = null) { if (empty($path)) { throw new ValidationException("Cannot construct AbsoluteResourceTemplate from empty string"); @@ -96,7 +96,7 @@ public function render(array $bindings) /** * @inheritdoc */ - public function matches($path) + public function matches(string $path) { try { $this->match($path); @@ -109,7 +109,7 @@ public function matches($path) /** * @inheritdoc */ - public function match($path) + public function match(string $path) { if (empty($path)) { throw $this->matchException($path, "path cannot be empty"); @@ -124,7 +124,7 @@ public function match($path) return $this->resourceTemplate->match(substr($path, 1, $verbSeparatorPos - 1)); } - private function matchException($path, $reason) + private function matchException(string $path, string $reason) { return new ValidationException("Could not match path '$path' to template '$this': $reason"); } @@ -134,7 +134,7 @@ private function renderVerb() return $this->verb ? ':' . $this->verb : ''; } - private function verbSeparatorPos($path) + private function verbSeparatorPos(string $path) { $finalSeparatorPos = strrpos($path, '/'); $verbSeparatorPos = strrpos($path, ':', $finalSeparatorPos); diff --git a/src/ResourceTemplate/Parser.php b/src/ResourceTemplate/Parser.php index 588983936..24fd814cd 100644 --- a/src/ResourceTemplate/Parser.php +++ b/src/ResourceTemplate/Parser.php @@ -42,11 +42,11 @@ class Parser /** * Parses a path into an array of segments. * - * @param string $path + * @param string|null $path * @return array * @throws ValidationException */ - public static function parseSegments($path) + public static function parseSegments(string $path = null) { if (empty($path)) { throw new ValidationException("Cannot parse empty path"); @@ -72,7 +72,7 @@ public static function parseSegments($path) * @return Segment * @throws ValidationException */ - private static function parseSegmentFromPath($path, &$nextLiteral, &$index) + private static function parseSegmentFromPath(string $path, string &$nextLiteral, int &$index) { if ($index >= strlen($path)) { // A trailing '/' has caused the index to exceed the bounds @@ -131,7 +131,7 @@ private static function parseSegmentFromPath($path, &$nextLiteral, &$index) * @return Segment * @throws ValidationException */ - private static function parse($segmentString, $path, $index) + private static function parse(string $segmentString, string $path, int $index) { if ($segmentString === '*') { return new Segment(Segment::WILDCARD_SEGMENT); @@ -156,7 +156,7 @@ private static function parse($segmentString, $path, $index) * @return Segment * @throws ValidationException */ - private static function parseVariableSegment($segmentStringWithoutBraces, $separatorLiteral) + private static function parseVariableSegment(string $segmentStringWithoutBraces, string $separatorLiteral) { // Validate there are no nested braces $nestedOpenBracket = strpos($segmentStringWithoutBraces, '{'); @@ -192,7 +192,7 @@ private static function parseVariableSegment($segmentStringWithoutBraces, $separ * @return string * @throws ValidationException */ - private static function parseLiteralFromPath($literal, $path, &$index) + private static function parseLiteralFromPath(string $literal, string $path, int &$index) { $literalLength = strlen($literal); if (strlen($path) < ($index + $literalLength)) { @@ -206,7 +206,7 @@ private static function parseLiteralFromPath($literal, $path, &$index) return $consumedLiteral; } - private static function parseError($path, $index, $reason) + private static function parseError(string $path, int $index, string $reason) { return new ValidationException("Error parsing '$path' at index $index: $reason"); } @@ -218,7 +218,7 @@ private static function parseError($path, $index, $reason) * @param string $literal * @return bool */ - private static function isValidLiteral($literal) + private static function isValidLiteral(string $literal) { return preg_match("/^[0-9a-zA-Z\\.\\-~_]+$/", $literal) === 1; } diff --git a/src/ResourceTemplate/RelativeResourceTemplate.php b/src/ResourceTemplate/RelativeResourceTemplate.php index fd7f196f6..2f25f5f4b 100644 --- a/src/ResourceTemplate/RelativeResourceTemplate.php +++ b/src/ResourceTemplate/RelativeResourceTemplate.php @@ -60,7 +60,7 @@ class RelativeResourceTemplate implements ResourceTemplateInterface * @param string $path * @throws ValidationException */ - public function __construct($path) + public function __construct(string $path = null) { if (empty($path)) { $msg = sprintf( @@ -139,7 +139,7 @@ public function render(array $bindings) /** * @inheritdoc */ - public function matches($path) + public function matches(string $path = null) { try { $this->match($path); @@ -152,7 +152,7 @@ public function matches($path) /** * @inheritdoc */ - public function match($path) + public function match(string $path = null) { // High level strategy for matching: // - Build a list of Segments from our template, where any variable segments are @@ -270,12 +270,15 @@ public function match($path) return $collapsedBindings; } - private function matchException($path, $reason) + /** + * @param string|null $path + */ + private function matchException($path, string $reason) { return new ValidationException("Could not match path '$path' to template '$this': $reason"); } - private function renderingException($bindings, $reason) + private function renderingException(array $bindings, string $reason) { $bindingsString = print_r($bindings, true); return new ValidationException( @@ -289,7 +292,7 @@ private function renderingException($bindings, $reason) * @param string|null $separator An optional string separator * @return array[] A list of [string, Segment] tuples */ - private static function buildKeySegmentTuples(array $segments, $separator = null) + private static function buildKeySegmentTuples(array $segments, string $separator = null) { $keySegmentTuples = []; $positionalArgumentCounter = 0; @@ -377,7 +380,7 @@ private static function countDoubleWildcards(array $segments) * @param array $segmentsToRender * @return string */ - private static function renderSegments($segmentsToRender) + private static function renderSegments(array $segmentsToRender) { $renderResult = ""; for ($i = 0; $i < count($segmentsToRender); $i++) { diff --git a/src/ResourceTemplate/ResourceTemplateInterface.php b/src/ResourceTemplate/ResourceTemplateInterface.php index 1b1b80f2b..165909ed2 100644 --- a/src/ResourceTemplate/ResourceTemplateInterface.php +++ b/src/ResourceTemplate/ResourceTemplateInterface.php @@ -74,7 +74,7 @@ public function render(array $bindings); * @param string $path A resource string. * @return bool */ - public function matches($path); + public function matches(string $path); /** * Matches a given $path to a resource template, and returns an array of bindings between @@ -85,5 +85,5 @@ public function matches($path); * @throws ValidationException if path can't be matched to the template. * @return array Array matching var names to binding values. */ - public function match($path); + public function match(string $path); } diff --git a/src/ResourceTemplate/Segment.php b/src/ResourceTemplate/Segment.php index 79b447b37..5ff86fa4a 100644 --- a/src/ResourceTemplate/Segment.php +++ b/src/ResourceTemplate/Segment.php @@ -74,11 +74,11 @@ class Segment * @throws ValidationException */ public function __construct( - $segmentType, - $value = null, - $key = null, + int $segmentType, + string $value = null, + string $key = null, RelativeResourceTemplate $template = null, - $separator = '/' + string $separator = '/' ) { $this->segmentType = $segmentType; $this->value = $value; @@ -117,19 +117,19 @@ public function __toString() /** * Checks if $value matches this Segment. * - * @param string $value + * @param string|null $value * @return bool * @throws ValidationException */ - public function matches($value) + public function matches(string $value = null) { switch ($this->segmentType) { case Segment::LITERAL_SEGMENT: return $this->value === $value; case Segment::WILDCARD_SEGMENT: - return self::isValidBinding($value); + return self::isValidBinding((string) $value); case Segment::DOUBLE_WILDCARD_SEGMENT: - return self::isValidDoubleWildcardBinding($value); + return self::isValidDoubleWildcardBinding((string) $value); case Segment::VARIABLE_SEGMENT: return $this->template->matches($value); default: @@ -186,7 +186,7 @@ public function getSeparator() * @param string $binding * @return bool */ - private static function isValidBinding($binding) + private static function isValidBinding(string $binding) { return preg_match("-^[^/]+$-", $binding) === 1; } @@ -198,7 +198,7 @@ private static function isValidBinding($binding) * @param string $binding * @return bool */ - private static function isValidDoubleWildcardBinding($binding) + private static function isValidDoubleWildcardBinding(string $binding) { return preg_match("-^.+$-", $binding) === 1; } diff --git a/src/RetrySettings.php b/src/RetrySettings.php index 5fa70554b..c8af73292 100644 --- a/src/RetrySettings.php +++ b/src/RetrySettings.php @@ -285,9 +285,9 @@ public function __construct(array $settings) * @return RetrySettings[] $retrySettings */ public static function load( - $serviceName, - $clientConfig, - $disableRetries = false + string $serviceName, + array $clientConfig, + bool $disableRetries = false ) { $serviceRetrySettings = []; @@ -386,7 +386,7 @@ public function with(array $settings) * @param int $timeout The timeout in milliseconds to be used as a logical call timeout. * @return array */ - public static function logicalTimeout($timeout) + public static function logicalTimeout(int $timeout) { return [ 'initialRpcTimeoutMillis' => $timeout, @@ -489,7 +489,7 @@ public function getTotalTimeoutMillis() return $this->totalTimeoutMillis; } - private static function convertArrayFromSnakeCase($settings) + private static function convertArrayFromSnakeCase(array $settings) { $camelCaseSettings = []; foreach ($settings as $key => $value) { diff --git a/src/Serializer.php b/src/Serializer.php index ae72cf5f6..ff983b706 100644 --- a/src/Serializer.php +++ b/src/Serializer.php @@ -118,7 +118,7 @@ public function encodeMessage($message) * @return mixed * @throws ValidationException */ - public function decodeMessage($message, $data) + public function decodeMessage($message, array $data) { // Get message descriptor $pool = DescriptorPool::getGeneratedPool(); @@ -139,7 +139,7 @@ public function decodeMessage($message, $data) * @return string Json representation of $message * @throws ValidationException */ - public static function serializeToJson($message) + public static function serializeToJson(Message $message) { return json_encode(self::serializeToPhpArray($message), JSON_PRETTY_PRINT); } @@ -149,7 +149,7 @@ public static function serializeToJson($message) * @return array PHP array representation of $message * @throws ValidationException */ - public static function serializeToPhpArray($message) + public static function serializeToPhpArray(Message $message) { return self::getPhpArraySerializer()->encodeMessage($message); } @@ -160,7 +160,7 @@ public static function serializeToPhpArray($message) * @param array $metadata * @return array */ - public static function decodeMetadata($metadata) + public static function decodeMetadata(array $metadata = null) { if (is_null($metadata) || count($metadata) == 0) { return []; @@ -231,7 +231,7 @@ public static function decodeAnyMessages($anyArray) /** * @param FieldDescriptor $field - * @param array $data + * @param Message|array|string $data * @return mixed * @throws \Exception */ @@ -290,7 +290,7 @@ private function getDescriptorMaps(Descriptor $descriptor) * @return array * @throws \Exception */ - private function encodeMessageImpl($message, Descriptor $messageType) + private function encodeMessageImpl(Message $message, Descriptor $messageType) { $data = []; @@ -379,7 +379,7 @@ private function decodeElement(FieldDescriptor $field, $data) * @return mixed * @throws \Exception */ - private function decodeMessageImpl($message, Descriptor $messageType, $data) + private function decodeMessageImpl(Message $message, Descriptor $messageType, array $data) { list($fieldsByName, $_) = $this->getDescriptorMaps($messageType); foreach ($data as $key => $v) { @@ -431,7 +431,7 @@ private function decodeMessageImpl($message, Descriptor $messageType, $data) * @param string $name * @return string Getter function */ - public static function getGetter($name) + public static function getGetter(string $name) { return 'get' . ucfirst(self::toCamelCase($name)); } @@ -440,7 +440,7 @@ public static function getGetter($name) * @param string $name * @return string Setter function */ - public static function getSetter($name) + public static function getSetter(string $name) { return 'set' . ucfirst(self::toCamelCase($name)); } @@ -451,7 +451,7 @@ public static function getSetter($name) * @param string $key * @return string */ - public static function toSnakeCase($key) + public static function toSnakeCase(string $key) { return strtolower(preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $key)); } @@ -462,12 +462,12 @@ public static function toSnakeCase($key) * @param string $key * @return string */ - public static function toCamelCase($key) + public static function toCamelCase(string $key) { return lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $key)))); } - private static function hasBinaryHeaderSuffix($key) + private static function hasBinaryHeaderSuffix(string $key) { return substr_compare($key, "-bin", strlen($key) - 4) === 0; } diff --git a/src/ServerStream.php b/src/ServerStream.php index b9c632591..3ccf14aae 100644 --- a/src/ServerStream.php +++ b/src/ServerStream.php @@ -32,6 +32,7 @@ namespace Google\ApiCore; use Google\Rpc\Code; +use Google\ApiCore\Testing\MockServerStreamingCall; /** * ServerStream is the response object from a server streaming API call. diff --git a/src/ServiceAddressTrait.php b/src/ServiceAddressTrait.php index 955edbf5c..9234c90bc 100644 --- a/src/ServiceAddressTrait.php +++ b/src/ServiceAddressTrait.php @@ -47,7 +47,7 @@ trait ServiceAddressTrait * @return array * @throws ValidationException */ - private static function normalizeServiceAddress($apiEndpoint) + private static function normalizeServiceAddress(string $apiEndpoint) { $components = explode(':', $apiEndpoint); if (count($components) == 2) { diff --git a/src/Testing/GeneratedTest.php b/src/Testing/GeneratedTest.php index 1b972549a..b3789f25a 100644 --- a/src/Testing/GeneratedTest.php +++ b/src/Testing/GeneratedTest.php @@ -39,6 +39,10 @@ abstract class GeneratedTest extends TestCase { + /** + * @param mixed $expected + * @param mixed $actual + */ public function assertProtobufEquals(&$expected, &$actual) { if ($expected === $actual) { @@ -81,6 +85,9 @@ public function assertProtobufEquals(&$expected, &$actual) } } + /** + * @param iterable $field + */ private function getValues($field) { return array_values( diff --git a/src/Testing/MockBidiStreamingCall.php b/src/Testing/MockBidiStreamingCall.php index 59cea91a6..6165d6edc 100644 --- a/src/Testing/MockBidiStreamingCall.php +++ b/src/Testing/MockBidiStreamingCall.php @@ -36,6 +36,7 @@ use Google\Protobuf\Internal\Message; use Google\Rpc\Code; use Grpc; +use stdClass; /** * The MockBidiStreamingCall class is used to mock out the \Grpc\BidiStreamingCall class @@ -53,10 +54,10 @@ class MockBidiStreamingCall extends Grpc\BidiStreamingCall /** * MockBidiStreamingCall constructor. * @param mixed[] $responses A list of response objects. - * @param callable|null $deserialize An optional deserialize method for the response object. - * @param MockStatus|null $status An optional status object. If set to null, a status of OK is used. + * @param callable|array|null $deserialize An optional deserialize method for the response object. + * @param stdClass|null $status An optional status object. If set to null, a status of OK is used. */ - public function __construct($responses, $deserialize = null, $status = null) + public function __construct(array $responses, $deserialize = null, stdClass $status = null) { $this->responses = $responses; $this->deserialize = $deserialize; @@ -97,7 +98,7 @@ public function read() } /** - * @return MockStatus|null|\stdClass + * @return stdClass|null * @throws ApiException */ public function getStatus() @@ -121,7 +122,7 @@ public function getStatus() /** * Save the request object, to be retrieved via getReceivedCalls() - * @param \Google\Protobuf\Internal\Message|mixed $request The request object + * @param Message|mixed $request The request object * @param array $options An array of options. * @throws ApiException */ diff --git a/src/Testing/MockClientStreamingCall.php b/src/Testing/MockClientStreamingCall.php index d5691cc3f..26f05b81e 100644 --- a/src/Testing/MockClientStreamingCall.php +++ b/src/Testing/MockClientStreamingCall.php @@ -37,6 +37,7 @@ use Google\Protobuf\Internal\Message; use Google\Rpc\Code; use Grpc; +use stdClass; /** * The MockClientStreamingCall class is used to mock out the \Grpc\ClientStreamingCall class @@ -55,11 +56,11 @@ class MockClientStreamingCall extends Grpc\ClientStreamingCall /** * MockClientStreamingCall constructor. - * @param Message $response The response object. - * @param callable|null $deserialize An optional deserialize method for the response object. - * @param MockStatus|null $status An optional status object. If set to null, a status of OK is used. + * @param Message|string $response The response object. + * @param callable|array|null $deserialize An optional deserialize method for the response object. + * @param stdClass|null $status An optional status object. If set to null, a status of OK is used. */ - public function __construct($response, $deserialize = null, $status = null) + public function __construct($response, $deserialize = null, stdClass $status = null) { $this->mockUnaryCall = new MockUnaryCall($response, $deserialize, $status); } @@ -76,7 +77,7 @@ public function wait() /** * Save the request object, to be retrieved via getReceivedCalls() - * @param \Google\Protobuf\Internal\Message|mixed $request The request object + * @param Message|mixed $request The request object * @param array $options An array of options * @throws ApiException */ diff --git a/src/Testing/MockGrpcTransport.php b/src/Testing/MockGrpcTransport.php index 4a5b23511..41a71efab 100644 --- a/src/Testing/MockGrpcTransport.php +++ b/src/Testing/MockGrpcTransport.php @@ -40,6 +40,9 @@ class MockGrpcTransport extends GrpcTransport private $requestArguments; private $mockCall; + /** + * @param mixed $mockCall + */ public function __construct($mockCall = null) { $this->mockCall = $mockCall; @@ -47,6 +50,11 @@ public function __construct($mockCall = null) parent::__construct('', $opts); } + /** + * @param string $method + * @param array $arguments + * @param callable $deserialize + */ protected function _simpleRequest( $method, $arguments, @@ -58,6 +66,10 @@ protected function _simpleRequest( return $this->mockCall; } + /** + * @param string $method + * @param callable $deserialize + */ protected function _clientStreamRequest( $method, $deserialize, @@ -68,6 +80,11 @@ protected function _clientStreamRequest( return $this->mockCall; } + /** + * @param string $method + * @param array $arguments + * @param callable $deserialize + */ protected function _serverStreamRequest( $method, $arguments, @@ -79,6 +96,10 @@ protected function _serverStreamRequest( return $this->mockCall; } + /** + * @param string $method + * @param callable $deserialize + */ protected function _bidiRequest( $method, $deserialize, @@ -89,11 +110,16 @@ protected function _bidiRequest( return $this->mockCall; } + /** + * @param string $method + * @param callable $deserialize + * @param array $arguments + */ private function logCall( $method, $deserialize, - $metadata = [], - $options = [], + array $metadata = [], + array $options = [], $arguments = null ) { $this->requestArguments = [ diff --git a/src/Testing/MockServerStreamingCall.php b/src/Testing/MockServerStreamingCall.php index 9b174cbfa..57f953103 100644 --- a/src/Testing/MockServerStreamingCall.php +++ b/src/Testing/MockServerStreamingCall.php @@ -34,6 +34,7 @@ use Google\ApiCore\ApiException; use Google\ApiCore\ApiStatus; +use Google\ApiCore\ServerStreamingCallInterface; use Google\Rpc\Code; use stdClass; @@ -41,7 +42,7 @@ * The MockServerStreamingCall class is used to mock out the \Grpc\ServerStreamingCall class * (https://github.com/grpc/grpc/blob/master/src/php/lib/Grpc/ServerStreamingCall.php) */ -class MockServerStreamingCall extends \Grpc\ServerStreamingCall +class MockServerStreamingCall extends \Grpc\ServerStreamingCall implements ServerStreamingCallInterface { use SerializationTrait; @@ -51,10 +52,10 @@ class MockServerStreamingCall extends \Grpc\ServerStreamingCall /** * MockServerStreamingCall constructor. * @param mixed[] $responses A list of response objects. - * @param callable|null $deserialize An optional deserialize method for the response object. - * @param MockStatus|stdClass|null $status An optional status object. If set to null, a status of OK is used. + * @param callable|array|null $deserialize An optional deserialize method for the response object. + * @param stdClass|null $status An optional status object. If set to null, a status of OK is used. */ - public function __construct($responses, $deserialize = null, $status = null) + public function __construct(array $responses, $deserialize = null, stdClass $status = null) { $this->responses = $responses; $this->deserialize = $deserialize; @@ -78,7 +79,7 @@ public function responses() } /** - * @return MockStatus|null|\stdClass + * @return stdClass|null * @throws ApiException */ public function getStatus() diff --git a/src/Testing/MockStatus.php b/src/Testing/MockStatus.php index dfaf7ea70..fb5ea340e 100644 --- a/src/Testing/MockStatus.php +++ b/src/Testing/MockStatus.php @@ -33,14 +33,18 @@ namespace Google\ApiCore\Testing; use Google\Rpc\Code; +use stdClass; -class MockStatus +/** + * @internal + */ +class MockStatus extends stdClass { - /** @var Code $code */ + /** @var Code|int $code */ public $code; public $details; public $metadata; - public function __construct($code, $details = null, array $metadata = []) + public function __construct($code, string $details = null, array $metadata = []) { $this->code = $code; $this->details = $details; diff --git a/src/Testing/MockStubTrait.php b/src/Testing/MockStubTrait.php index 8d4bd6405..ed9e15ddf 100644 --- a/src/Testing/MockStubTrait.php +++ b/src/Testing/MockStubTrait.php @@ -211,7 +211,7 @@ public function addResponse($response, $status = null) * * @param Status $status */ - public function setStreamingStatus($status) + public function setStreamingStatus(Status $status) { $this->serverStreamingStatus = $status; } @@ -261,7 +261,7 @@ public function isExhausted() * @param callable $deserialize * @return static An instance of the current class type. */ - public static function create($responseObject, $status = null, $deserialize = null) + public static function create($responseObject, Status $status = null, callable $deserialize = null) { $stub = new static($deserialize); // @phpstan-ignore-line $stub->addResponse($responseObject, $status); @@ -275,7 +275,7 @@ public static function create($responseObject, $status = null, $deserialize = nu * @param Status $finalStatus * @return static An instance of the current class type. */ - public static function createWithResponseSequence($sequence, $deserialize = null, $finalStatus = null) + public static function createWithResponseSequence(array $sequence, callable $deserialize = null, Status $finalStatus = null) { $stub = new static($deserialize); // @phpstan-ignore-line foreach ($sequence as $elem) { diff --git a/src/Testing/MockTransport.php b/src/Testing/MockTransport.php index a91789a47..2e7c18113 100644 --- a/src/Testing/MockTransport.php +++ b/src/Testing/MockTransport.php @@ -90,7 +90,7 @@ public function startServerStreamingCall(Call $call, array $options) return new ServerStream($response, $call->getDescriptor()); } - public function __call($name, $arguments) + public function __call(string $name, array $arguments) { $call = $arguments[0]; $options = $arguments[1]; diff --git a/src/Testing/MockUnaryCall.php b/src/Testing/MockUnaryCall.php index 9270e2173..19edcee21 100644 --- a/src/Testing/MockUnaryCall.php +++ b/src/Testing/MockUnaryCall.php @@ -33,6 +33,8 @@ namespace Google\ApiCore\Testing; use Google\Rpc\Code; +use Google\Protobuf\Internal\Message; +use stdClass; /** * The MockUnaryCall class is used to mock out the \Grpc\UnaryCall class @@ -51,11 +53,11 @@ class MockUnaryCall extends \Grpc\UnaryCall /** * MockUnaryCall constructor. - * @param \Google\Protobuf\Internal\Message $response The response object. - * @param callable|null $deserialize An optional deserialize method for the response object. - * @param MockStatus|null $status An optional status object. If set to null, a status of OK is used. + * @param Message|string|null $response The response object. + * @param callable|array|null $deserialize An optional deserialize method for the response object. + * @param stdClass|null $status An optional status object. If set to null, a status of OK is used. */ - public function __construct($response, $deserialize = null, $status = null) + public function __construct($response = null, $deserialize = null, stdClass $status = null) { $this->response = $response; $this->deserialize = $deserialize; diff --git a/src/Testing/SerializationTrait.php b/src/Testing/SerializationTrait.php index d63d8d450..8f8045e7d 100644 --- a/src/Testing/SerializationTrait.php +++ b/src/Testing/SerializationTrait.php @@ -35,6 +35,10 @@ trait SerializationTrait { + /** + * @param mixed $message + * @param mixed $deserialize + */ protected function deserializeMessage($message, $deserialize) { if ($message === null) { diff --git a/src/Transport/Grpc/ForwardingCall.php b/src/Transport/Grpc/ForwardingCall.php index bd0b42055..f5b3fd87f 100644 --- a/src/Transport/Grpc/ForwardingCall.php +++ b/src/Transport/Grpc/ForwardingCall.php @@ -41,7 +41,9 @@ */ abstract class ForwardingCall { - /** @var AbstractCall */ + /** + * @var AbstractCall|ForwardingCall + */ protected $innerCall; /** diff --git a/src/Transport/Grpc/ServerStreamingCallWrapper.php b/src/Transport/Grpc/ServerStreamingCallWrapper.php index fe8773f6c..018e59d99 100644 --- a/src/Transport/Grpc/ServerStreamingCallWrapper.php +++ b/src/Transport/Grpc/ServerStreamingCallWrapper.php @@ -42,6 +42,9 @@ */ class ServerStreamingCallWrapper implements ServerStreamingCallInterface { + /** + * @var ServerStreamingCall|GCPServerStreamCall + */ private $stream; /** diff --git a/src/Transport/GrpcFallbackTransport.php b/src/Transport/GrpcFallbackTransport.php index dc19c2974..e186ca922 100644 --- a/src/Transport/GrpcFallbackTransport.php +++ b/src/Transport/GrpcFallbackTransport.php @@ -61,7 +61,7 @@ class GrpcFallbackTransport implements TransportInterface * @param callable $httpHandler A handler used to deliver PSR-7 requests. */ public function __construct( - $baseUri, + string $baseUri, callable $httpHandler ) { $this->baseUri = $baseUri; @@ -82,7 +82,7 @@ public function __construct( * @return GrpcFallbackTransport * @throws ValidationException */ - public static function build($apiEndpoint, array $config = []) + public static function build(string $apiEndpoint, array $config = []) { $config += [ 'httpHandler' => null, diff --git a/src/Transport/GrpcTransport.php b/src/Transport/GrpcTransport.php index 9dfd65580..aa0154668 100644 --- a/src/Transport/GrpcTransport.php +++ b/src/Transport/GrpcTransport.php @@ -77,7 +77,7 @@ class GrpcTransport extends BaseStub implements TransportInterface * extends {@see Grpc\Interceptor}. * @throws Exception */ - public function __construct($hostname, $opts, Channel $channel = null, array $interceptors = []) + public function __construct(string $hostname, array $opts, Channel $channel = null, array $interceptors = []) { if ($interceptors) { $channel = Interceptor::intercept( @@ -113,7 +113,7 @@ public function __construct($hostname, $opts, Channel $channel = null, array $in * @return GrpcTransport * @throws ValidationException */ - public static function build($apiEndpoint, array $config = []) + public static function build(string $apiEndpoint, array $config = []) { self::validateGrpcSupport(); $config += [ diff --git a/src/Transport/Rest/JsonStreamDecoder.php b/src/Transport/Rest/JsonStreamDecoder.php index 517f01e28..879d88042 100644 --- a/src/Transport/Rest/JsonStreamDecoder.php +++ b/src/Transport/Rest/JsonStreamDecoder.php @@ -86,7 +86,7 @@ class JsonStreamDecoder * * @experimental */ - public function __construct(StreamInterface $stream, $decodeType, $options = []) + public function __construct(StreamInterface $stream, string $decodeType, array $options = []) { $this->stream = $stream; $this->decodeType = $decodeType; diff --git a/src/Transport/Rest/RestServerStreamingCall.php b/src/Transport/Rest/RestServerStreamingCall.php index 3ff560dd8..d13a9f820 100644 --- a/src/Transport/Rest/RestServerStreamingCall.php +++ b/src/Transport/Rest/RestServerStreamingCall.php @@ -88,7 +88,7 @@ class RestServerStreamingCall implements ServerStreamingCallInterface * @param string $decodeType * @param array $decoderOptions */ - public function __construct($httpHandler, $decodeType, array $decoderOptions) + public function __construct(callable $httpHandler, string $decodeType, array $decoderOptions) { $this->httpHandler = $httpHandler; $this->decodeType = $decodeType; @@ -130,7 +130,7 @@ public function start($request, array $headers = [], array $callOptions = []) * @param array $headers * @return RequestInterface */ - private function appendHeaders($request, $headers) + private function appendHeaders(RequestInterface $request, array $headers) { foreach ($headers as $key => $value) { $request = $request->hasHeader($key) ? @@ -166,7 +166,7 @@ public function responses() * Return the status of the server stream. If the call has not been started * this will be null. * - * @return \stdClass The status, with integer $code, string + * @return stdClass The status, with integer $code, string * $details, and array $metadata members */ public function getStatus() diff --git a/src/Transport/RestTransport.php b/src/Transport/RestTransport.php index c4c25745f..d4309600e 100644 --- a/src/Transport/RestTransport.php +++ b/src/Transport/RestTransport.php @@ -91,7 +91,7 @@ public function __construct( * @return RestTransport * @throws ValidationException */ - public static function build($apiEndpoint, $restConfigPath, array $config = []) + public static function build(string $apiEndpoint, string $restConfigPath, array $config = []) { $config += [ 'httpHandler' => null, diff --git a/src/ValidationTrait.php b/src/ValidationTrait.php index 85ed31124..294036794 100644 --- a/src/ValidationTrait.php +++ b/src/ValidationTrait.php @@ -38,7 +38,7 @@ trait ValidationTrait * @param array $requiredKeys List of keys to check for in $arr * @return array Returns $arr for fluent use */ - public static function validate($arr, $requiredKeys) + public static function validate(array $arr, array $requiredKeys) { return self::validateImpl($arr, $requiredKeys, true); } @@ -48,7 +48,7 @@ public static function validate($arr, $requiredKeys) * @param array $requiredKeys List of keys to check for in $arr * @return array Returns $arr for fluent use */ - public static function validateNotNull($arr, $requiredKeys) + public static function validateNotNull(array $arr, array $requiredKeys) { return self::validateImpl($arr, $requiredKeys, false); } @@ -69,7 +69,7 @@ private static function validateImpl($arr, $requiredKeys, $allowNull) * @param string $filePath * @throws ValidationException */ - private static function validateFileExists($filePath) + private static function validateFileExists(string $filePath) { if (!file_exists($filePath)) { throw new ValidationException("Could not find specified file: $filePath"); diff --git a/src/Version.php b/src/Version.php index 68d696ee5..cad69ae0e 100644 --- a/src/Version.php +++ b/src/Version.php @@ -57,7 +57,7 @@ public static function getApiCoreVersion() * @param string $file * @return string */ - public static function readVersionFile($file) + public static function readVersionFile(string $file) { $versionString = file_exists($file) ? (string) file_get_contents($file) diff --git a/tests/Tests/Unit/GapicClientTraitTest.php b/tests/Tests/Unit/GapicClientTraitTest.php index 443d219ae..242c048a6 100644 --- a/tests/Tests/Unit/GapicClientTraitTest.php +++ b/tests/Tests/Unit/GapicClientTraitTest.php @@ -469,8 +469,7 @@ public function setClientOptionsData() $clientDefaults = GapicClientTraitStub::getClientDefaults(); $expectedRetrySettings = RetrySettings::load( $clientDefaults['serviceName'], - json_decode(file_get_contents($clientDefaults['clientConfig']), true), - [] + json_decode(file_get_contents($clientDefaults['clientConfig']), true) ); $disabledRetrySettings = []; foreach ($expectedRetrySettings as $method => $retrySettingsItem) { diff --git a/tests/Tests/Unit/PageTest.php b/tests/Tests/Unit/PageTest.php index 64e900374..912aafde4 100644 --- a/tests/Tests/Unit/PageTest.php +++ b/tests/Tests/Unit/PageTest.php @@ -66,7 +66,7 @@ private function createPage($responseSequence) }); }; - $call = new Call('method', [], $mockRequest); + $call = new Call('method', null, $mockRequest); $options = []; $response = $callable($call, $options)->wait(); diff --git a/tests/Tests/Unit/PagedListResponseTest.php b/tests/Tests/Unit/PagedListResponseTest.php index bcf669e3e..9e0c8c8c2 100644 --- a/tests/Tests/Unit/PagedListResponseTest.php +++ b/tests/Tests/Unit/PagedListResponseTest.php @@ -98,7 +98,7 @@ private function makeMockPagedCall($mockRequest, $mockResponse, $resourceField = }); }; - $call = new Call('method', [], $mockRequest); + $call = new Call('method', null, $mockRequest); $options = []; $response = $callable($call, $options)->wait(); diff --git a/tests/Tests/Unit/ResourceTemplate/ParserTest.php b/tests/Tests/Unit/ResourceTemplate/ParserTest.php index 79fd73ebf..8aacab4e6 100644 --- a/tests/Tests/Unit/ResourceTemplate/ParserTest.php +++ b/tests/Tests/Unit/ResourceTemplate/ParserTest.php @@ -308,7 +308,6 @@ public function testFailIsValidLiteral($literal) public function invalidLiterals() { return [ - [null], [""], ["fo\$o"], ["fo{o"], @@ -366,7 +365,6 @@ public function testFailIsValidBinding($binding) public function invalidBindings() { return [ - [null], [""], ["fo/o"], ]; @@ -403,7 +401,6 @@ public function testFailIsValidDoubleWildcardBinding($binding) public function invalidDoubleWildcardBindings() { return [ - [null], [""], ]; } From d67d93ac4ca7e9105b78f9d4bf13a8c9e82770fd Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 10 Aug 2022 09:41:53 -0700 Subject: [PATCH 3/4] clean up nullable types --- src/ApiException.php | 4 ++-- .../AbsoluteResourceTemplate.php | 6 +++--- .../RelativeResourceTemplate.php | 19 ++++++------------- src/ResourceTemplate/Segment.php | 8 ++++---- src/Serializer.php | 4 ++-- src/ServerStream.php | 1 - src/Testing/MockBidiStreamingCall.php | 2 +- .../AbsoluteResourceTemplateTest.php | 1 - .../RelativeResourceTemplateTest.php | 4 ---- 9 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/ApiException.php b/src/ApiException.php index 3e8b03b59..b84585e28 100644 --- a/src/ApiException.php +++ b/src/ApiException.php @@ -149,7 +149,7 @@ public static function createFromStdClass(stdClass $status) $status->details, $status->code, $metadata, - Serializer::decodeMetadata($metadata) + Serializer::decodeMetadata((array) $metadata) ); } @@ -170,7 +170,7 @@ public static function createFromApiResponse( $basicMessage, $rpcCode, $metadata, - Serializer::decodeMetadata($metadata), + Serializer::decodeMetadata((array) $metadata), $previous ); } diff --git a/src/ResourceTemplate/AbsoluteResourceTemplate.php b/src/ResourceTemplate/AbsoluteResourceTemplate.php index 5073655dd..8da609ed1 100644 --- a/src/ResourceTemplate/AbsoluteResourceTemplate.php +++ b/src/ResourceTemplate/AbsoluteResourceTemplate.php @@ -61,13 +61,13 @@ class AbsoluteResourceTemplate implements ResourceTemplateInterface /** * AbsoluteResourceTemplate constructor. - * @param string|null $path + * @param string $path * @throws ValidationException */ - public function __construct(string $path = null) + public function __construct(string $path) { if (empty($path)) { - throw new ValidationException("Cannot construct AbsoluteResourceTemplate from empty string"); + throw new ValidationException('Cannot construct AbsoluteResourceTemplate from empty string'); } if ($path[0] !== '/') { throw new ValidationException( diff --git a/src/ResourceTemplate/RelativeResourceTemplate.php b/src/ResourceTemplate/RelativeResourceTemplate.php index fdd2f3707..f31586891 100644 --- a/src/ResourceTemplate/RelativeResourceTemplate.php +++ b/src/ResourceTemplate/RelativeResourceTemplate.php @@ -62,14 +62,10 @@ class RelativeResourceTemplate implements ResourceTemplateInterface * @param string $path * @throws ValidationException */ - public function __construct(string $path = null) + public function __construct(string $path) { if (empty($path)) { - $msg = sprintf( - "Cannot construct RelativeResourceTemplate from %s string", - is_null($path) ? "null" : "empty" - ); - throw new ValidationException($msg); + throw new ValidationException('Cannot construct RelativeResourceTemplate from empty string'); } $this->segments = Parser::parseSegments($path); @@ -119,7 +115,7 @@ public function render(array $bindings) throw $this->renderingException($bindings, "missing required binding '$key' for segment '$segment'"); } $value = $bindings[$key]; - if ($segment->matches($value)) { + if (!is_null($value) && $segment->matches($value)) { $literalSegments[] = new Segment( Segment::LITERAL_SEGMENT, $value, @@ -141,7 +137,7 @@ public function render(array $bindings) /** * @inheritdoc */ - public function matches(string $path = null) + public function matches(string $path) { try { $this->match($path); @@ -154,7 +150,7 @@ public function matches(string $path = null) /** * @inheritdoc */ - public function match(string $path = null) + public function match(string $path) { // High level strategy for matching: // - Build a list of Segments from our template, where any variable segments are @@ -272,10 +268,7 @@ public function match(string $path = null) return $collapsedBindings; } - /** - * @param string|null $path - */ - private function matchException($path, string $reason) + private function matchException(string $path, string $reason) { return new ValidationException("Could not match path '$path' to template '$this': $reason"); } diff --git a/src/ResourceTemplate/Segment.php b/src/ResourceTemplate/Segment.php index a5d13d815..452ae83f7 100644 --- a/src/ResourceTemplate/Segment.php +++ b/src/ResourceTemplate/Segment.php @@ -118,19 +118,19 @@ public function __toString() /** * Checks if $value matches this Segment. * - * @param string|null $value + * @param string $value * @return bool * @throws ValidationException */ - public function matches(string $value = null) + public function matches(string $value) { switch ($this->segmentType) { case Segment::LITERAL_SEGMENT: return $this->value === $value; case Segment::WILDCARD_SEGMENT: - return self::isValidBinding((string) $value); + return self::isValidBinding($value); case Segment::DOUBLE_WILDCARD_SEGMENT: - return self::isValidDoubleWildcardBinding((string) $value); + return self::isValidDoubleWildcardBinding($value); case Segment::VARIABLE_SEGMENT: return $this->template->matches($value); default: diff --git a/src/Serializer.php b/src/Serializer.php index ff983b706..fab4a64f8 100644 --- a/src/Serializer.php +++ b/src/Serializer.php @@ -160,9 +160,9 @@ public static function serializeToPhpArray(Message $message) * @param array $metadata * @return array */ - public static function decodeMetadata(array $metadata = null) + public static function decodeMetadata(array $metadata) { - if (is_null($metadata) || count($metadata) == 0) { + if (count($metadata) == 0) { return []; } $result = []; diff --git a/src/ServerStream.php b/src/ServerStream.php index 3ccf14aae..b9c632591 100644 --- a/src/ServerStream.php +++ b/src/ServerStream.php @@ -32,7 +32,6 @@ namespace Google\ApiCore; use Google\Rpc\Code; -use Google\ApiCore\Testing\MockServerStreamingCall; /** * ServerStream is the response object from a server streaming API call. diff --git a/src/Testing/MockBidiStreamingCall.php b/src/Testing/MockBidiStreamingCall.php index 9b2d3f47c..7ac698015 100644 --- a/src/Testing/MockBidiStreamingCall.php +++ b/src/Testing/MockBidiStreamingCall.php @@ -56,7 +56,7 @@ class MockBidiStreamingCall extends Grpc\BidiStreamingCall /** * MockBidiStreamingCall constructor. * @param mixed[] $responses A list of response objects. - * @param callable|array|null $deserialize An optional deserialize method for the response object. + * @param mixed|null $deserialize An optional deserialize method for the response object. * @param stdClass|null $status An optional status object. If set to null, a status of OK is used. */ public function __construct(array $responses, $deserialize = null, stdClass $status = null) diff --git a/tests/Tests/Unit/ResourceTemplate/AbsoluteResourceTemplateTest.php b/tests/Tests/Unit/ResourceTemplate/AbsoluteResourceTemplateTest.php index fb185269a..c533ee357 100644 --- a/tests/Tests/Unit/ResourceTemplate/AbsoluteResourceTemplateTest.php +++ b/tests/Tests/Unit/ResourceTemplate/AbsoluteResourceTemplateTest.php @@ -85,7 +85,6 @@ public function testInvalidPaths($path) public function invalidPathProvider() { return [ - [null], // Null path [""], // Empty path ["foo"], // No leading '/' ["/foo:bar/baz"], // Action containing '/' diff --git a/tests/Tests/Unit/ResourceTemplate/RelativeResourceTemplateTest.php b/tests/Tests/Unit/ResourceTemplate/RelativeResourceTemplateTest.php index f41e7bd08..1523965da 100644 --- a/tests/Tests/Unit/ResourceTemplate/RelativeResourceTemplateTest.php +++ b/tests/Tests/Unit/ResourceTemplate/RelativeResourceTemplateTest.php @@ -88,10 +88,6 @@ public function testInvalidPaths($path, $expectedExceptionMessage = null) public function invalidPathProvider() { return [ - [ - null, // Null path - "Cannot construct RelativeResourceTemplate from null string" - ], [ "", // Empty path "Cannot construct RelativeResourceTemplate from empty string" From 07bbdd293dd3c43e6346bcc5e52ce8f4f811d129 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 10 Aug 2022 09:48:49 -0700 Subject: [PATCH 4/4] simplify iterable type, remove nullables --- src/ApiException.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ApiException.php b/src/ApiException.php index b84585e28..f25f9e8b5 100644 --- a/src/ApiException.php +++ b/src/ApiException.php @@ -234,7 +234,7 @@ private static function containsErrorInfo(array $decodedMetadata) * * @param string $basicMessage * @param int $rpcCode - * @param array|RepeatedField $metadata + * @param iterable|null $metadata * @param array $decodedMetadata * @param Exception|null $previous * @return ApiException @@ -242,8 +242,8 @@ private static function containsErrorInfo(array $decodedMetadata) private static function create( string $basicMessage, int $rpcCode, - $metadata = null, - array $decodedMetadata = null, + $metadata, + array $decodedMetadata, Exception $previous = null ) { $containsErrorInfo = self::containsErrorInfo($decodedMetadata);