diff --git a/src/Google/Ads/GoogleAds/Lib/V16/GoogleAdsGapicClientTrait.php b/src/Google/Ads/GoogleAds/Lib/V16/GoogleAdsGapicClientTrait.php index 4fa4e0df8..04b32b374 100644 --- a/src/Google/Ads/GoogleAds/Lib/V16/GoogleAdsGapicClientTrait.php +++ b/src/Google/Ads/GoogleAds/Lib/V16/GoogleAdsGapicClientTrait.php @@ -43,6 +43,7 @@ trait GoogleAdsGapicClientTrait private $linkedCustomerId = null; private $unaryMiddlewares = []; private $streamingMiddlewares = []; + private ?GoogleAdsResponseMetadata $responseMetadata = null; /** * @see GapicClientTrait::modifyClientOptions() @@ -103,7 +104,7 @@ protected function modifyUnaryCallable(callable &$callable) { $callable = $this->addFixedHeaderMiddleware($callable); $callable = new UnaryGoogleAdsExceptionMiddleware($callable); - $callable = new UnaryGoogleAdsResponseMetadataCallable($callable); + $callable = new UnaryGoogleAdsResponseMetadataCallable($callable, $this); foreach ($this->unaryMiddlewares as $unaryMiddleware) { /** @var GoogleAdsMiddlewareAbstract $unaryMiddleware */ $callable = $unaryMiddleware->withNextHandler($callable); @@ -123,4 +124,14 @@ protected function modifyStreamingCallable(callable &$callable) $callable = $streamingMiddleware->withNextHandler($callable); } } + + public function getResponseMetadata(): ?GoogleAdsResponseMetadata + { + return $this->responseMetadata; + } + + public function setResponseMetadata(?GoogleAdsResponseMetadata $responseMetadata): void + { + $this->responseMetadata = $responseMetadata; + } } diff --git a/src/Google/Ads/GoogleAds/Lib/V16/UnaryGoogleAdsResponseMetadataCallable.php b/src/Google/Ads/GoogleAds/Lib/V16/UnaryGoogleAdsResponseMetadataCallable.php index c9583a59a..40f7d8f43 100644 --- a/src/Google/Ads/GoogleAds/Lib/V16/UnaryGoogleAdsResponseMetadataCallable.php +++ b/src/Google/Ads/GoogleAds/Lib/V16/UnaryGoogleAdsResponseMetadataCallable.php @@ -21,6 +21,8 @@ use Google\Ads\GoogleAds\Lib\GoogleAdsMiddlewareAbstract; use Google\ApiCore\Call; use Google\ApiCore\Middleware\ResponseMetadataMiddleware; +use GuzzleHttp\Promise\Promise; +use GuzzleHttp\Promise\PromiseInterface; /** * Callable for returning `GoogleAdsResponseMetadata` from unary calls to the API. @@ -29,24 +31,48 @@ class UnaryGoogleAdsResponseMetadataCallable extends GoogleAdsMiddlewareAbstract { use GoogleAdsMetadataTrait; + private $adsClient; + + public function __construct(callable $nextHandler = null, $adsClient = null) + { + $this->adsClient = $adsClient; + parent::__construct($nextHandler); + } /** * @param Call $call the current request * @param array $options the optional parameters - * @return array|\GuzzleHttp\Promise\PromiseInterface the two-member array of + * @return array|PromiseInterface the two-member array of * response and metadata if `withResponseMetadata` is specified as an option; * Or else, the `Promise` interface of the next handler */ public function __invoke(Call $call, array $options) { - if (!empty($options['withResponseMetadata'])) { - $next = new ResponseMetadataMiddleware($this->getNextHandler()); - return $next($call, $options)->then(function ($responseList) { - list($response, $metadata) = $responseList; - return [$response, new GoogleAdsResponseMetadata($metadata)]; - }); - } else { - $next = $this->getNextHandler(); - return $next($call, $options); + $next = $this->getNextHandler(); + if (empty($options['withResponseMetadata'])) { + // Bypass this middleware if the option is not set. + return $next($call, $options)->then( + function ($response) { + // Reset the metadata to null. + $this->adsClient->setResponseMetadata(null); + return $response; + } + ); } + + $metadataReceiver = new Promise(); + $options['metadataCallback'] = function ($metadata) use ($metadataReceiver) { + $metadataReceiver->resolve($metadata); + }; + return $next($call, $options)->then( + function ($response) use ($metadataReceiver) { + $metadata = null; + if ($metadataReceiver->getState() === PromiseInterface::FULFILLED) { + $metadata = new GoogleAdsResponseMetadata($metadataReceiver->wait()); + } + $this->adsClient->setResponseMetadata($metadata); + + return $response; + } + ); } }