| @@ -4,14 +4,17 @@ | ||
| 4 | 4 | |
| 5 | 5 | use Dudlewebs\WPMCS\s3\Aws\Api\ApiProvider; |
| 6 | 6 | use Dudlewebs\WPMCS\s3\Aws\Api\DocModel; |
| 7 | 7 | use Dudlewebs\WPMCS\s3\Aws\Api\Service; |
| 8 | -use Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ApiCallAttemptMonitoringMiddleware; | |
| 9 | -use Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ApiCallMonitoringMiddleware; | |
| 10 | -use Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ConfigurationProvider; | |
| 8 | +use Dudlewebs\WPMCS\s3\Aws\Auth\AuthSelectionMiddleware; | |
| 9 | +use Dudlewebs\WPMCS\s3\Aws\Auth\AuthSchemeResolverInterface; | |
| 11 | 10 | use Dudlewebs\WPMCS\s3\Aws\EndpointDiscovery\EndpointDiscoveryMiddleware; |
| 11 | +use Dudlewebs\WPMCS\s3\Aws\EndpointV2\EndpointProviderV2; | |
| 12 | +use Dudlewebs\WPMCS\s3\Aws\EndpointV2\EndpointV2Middleware; | |
| 13 | +use Dudlewebs\WPMCS\s3\Aws\Exception\AwsException; | |
| 12 | 14 | use Dudlewebs\WPMCS\s3\Aws\Signature\SignatureProvider; |
| 13 | 15 | use Dudlewebs\WPMCS\s3\GuzzleHttp\Psr7\Uri; |
| 16 | +use Dudlewebs\WPMCS\s3\Psr\Http\Message\RequestInterface; | |
| 14 | 17 | /** |
| 15 | 18 | * Default AWS client implementation |
| 16 | 19 | */ |
| 17 | 20 | class AwsClient implements AwsClientInterface |
| @@ -23,19 +26,33 @@ | ||
| 23 | 26 | private $config; |
| 24 | 27 | /** @var string */ |
| 25 | 28 | private $region; |
| 26 | 29 | /** @var string */ |
| 30 | + private $signingRegionSet; | |
| 31 | + /** @var string */ | |
| 27 | 32 | private $endpoint; |
| 28 | 33 | /** @var Service */ |
| 29 | 34 | private $api; |
| 30 | 35 | /** @var callable */ |
| 31 | 36 | private $signatureProvider; |
| 37 | + /** @var AuthSchemeResolverInterface */ | |
| 38 | + private $authSchemeResolver; | |
| 32 | 39 | /** @var callable */ |
| 33 | 40 | private $credentialProvider; |
| 41 | + /** @var callable */ | |
| 42 | + private $tokenProvider; | |
| 34 | 43 | /** @var HandlerList */ |
| 35 | 44 | private $handlerList; |
| 36 | 45 | /** @var array*/ |
| 37 | 46 | private $defaultRequestOptions; |
| 47 | + /** @var array*/ | |
| 48 | + private $clientContextParams = []; | |
| 49 | + /** @var array*/ | |
| 50 | + protected $clientBuiltIns = []; | |
| 51 | + /** @var EndpointProviderV2 | callable */ | |
| 52 | + protected $endpointProvider; | |
| 53 | + /** @var callable */ | |
| 54 | + protected $serializer; | |
| 38 | 55 | /** |
| 39 | 56 | * Get an array of client constructor arguments used by the client. |
| 40 | 57 | * |
| 41 | 58 | * @return array |
| @@ -59,8 +76,17 @@ | ||
| 59 | 76 | * credentials, or a callable credentials provider used to create |
| 60 | 77 | * credentials or return null. See Aws\Credentials\CredentialProvider for |
| 61 | 78 | * a list of built-in credentials providers. If no credentials are |
| 62 | 79 | * provided, the SDK will attempt to load them from the environment. |
| 80 | + * - token: | |
| 81 | + * (Aws\Token\TokenInterface|array|bool|callable) Specifies | |
| 82 | + * the token used to authorize requests. Provide an | |
| 83 | + * Aws\Token\TokenInterface object, an associative array of | |
| 84 | + * "token" and an optional "expires" key, `false` to use no | |
| 85 | + * token, or a callable token provider used to create a | |
| 86 | + * token or return null. See Aws\Token\TokenProvider for | |
| 87 | + * a list of built-in token providers. If no token is | |
| 88 | + * provided, the SDK will attempt to load one from the environment. | |
| 63 | 89 | * - csm: |
| 64 | 90 | * (Aws\ClientSideMonitoring\ConfigurationInterface|array|callable) Specifies |
| 65 | 91 | * the credentials used to sign requests. Provide an |
| 66 | 92 | * Aws\ClientSideMonitoring\ConfigurationInterface object, a callable |
| @@ -167,8 +193,25 @@ | ||
| 167 | 193 | * - validate: (bool, default=bool(true)) Set to false to disable |
| 168 | 194 | * client-side parameter validation. |
| 169 | 195 | * - version: (string, required) The version of the webservice to |
| 170 | 196 | * utilize (e.g., 2006-03-01). |
| 197 | + * - account_id_endpoint_mode: (string, default(preferred)) this option | |
| 198 | + * decides whether credentials should resolve an accountId value, | |
| 199 | + * which is going to be used as part of the endpoint resolution. | |
| 200 | + * The valid values for this option are: | |
| 201 | + * - preferred: when this value is set then, a warning is logged when | |
| 202 | + * accountId is empty in the resolved identity. | |
| 203 | + * - required: when this value is set then, an exception is thrown when | |
| 204 | + * accountId is empty in the resolved identity. | |
| 205 | + * - disabled: when this value is set then, the validation for if accountId | |
| 206 | + * was resolved or not, is ignored. | |
| 207 | + * - ua_append: (string, array) To pass custom user agent parameters. | |
| 208 | + * - app_id: (string) an optional application specific identifier that can be set. | |
| 209 | + * When set it will be appended to the User-Agent header of every request | |
| 210 | + * in the form of App/{AppId}. This variable is sourced from environment | |
| 211 | + * variable AWS_SDK_UA_APP_ID or the shared config profile attribute sdk_ua_app_id. | |
| 212 | + * See https://docs.aws.amazon.com/sdkref/latest/guide/settings-reference.html for | |
| 213 | + * more information on environment variables and shared config settings. | |
| 171 | 214 | * |
| 172 | 215 | * @param array $args Client configuration arguments. |
| 173 | 216 | * |
| 174 | 217 | * @throws \InvalidArgumentException if any required options are missing or |
| @@ -187,23 +230,40 @@ | ||
| 187 | 230 | $resolver = new ClientResolver(static::getArguments()); |
| 188 | 231 | $config = $resolver->resolve($args, $this->handlerList); |
| 189 | 232 | $this->api = $config['api']; |
| 190 | 233 | $this->signatureProvider = $config['signature_provider']; |
| 234 | + $this->authSchemeResolver = $config['auth_scheme_resolver']; | |
| 191 | 235 | $this->endpoint = new Uri($config['endpoint']); |
| 192 | 236 | $this->credentialProvider = $config['credentials']; |
| 193 | - $this->region = isset($config['region']) ? $config['region'] : null; | |
| 237 | + $this->tokenProvider = $config['token']; | |
| 238 | + $this->region = $config['region'] ?? null; | |
| 239 | + $this->signingRegionSet = $config['sigv4a_signing_region_set'] ?? null; | |
| 194 | 240 | $this->config = $config['config']; |
| 241 | + $this->setClientBuiltIns($args, $config); | |
| 242 | + $this->clientContextParams = $this->setClientContextParams($args); | |
| 195 | 243 | $this->defaultRequestOptions = $config['http']; |
| 196 | - $this->addSignatureMiddleware(); | |
| 244 | + $this->endpointProvider = $config['endpoint_provider']; | |
| 245 | + $this->serializer = $config['serializer']; | |
| 246 | + $this->addSignatureMiddleware($args); | |
| 197 | 247 | $this->addInvocationId(); |
| 198 | 248 | $this->addEndpointParameterMiddleware($args); |
| 199 | 249 | $this->addEndpointDiscoveryMiddleware($config, $args); |
| 250 | + $this->addRequestCompressionMiddleware($config); | |
| 200 | 251 | $this->loadAliases(); |
| 201 | 252 | $this->addStreamRequestPayload(); |
| 202 | 253 | $this->addRecursionDetection(); |
| 254 | + if ($this->isUseEndpointV2()) { | |
| 255 | + $this->addEndpointV2Middleware(); | |
| 256 | + } | |
| 257 | + $this->addAuthSelectionMiddleware($config['config']); | |
| 258 | + if (!\is_null($this->api->getMetadata('awsQueryCompatible'))) { | |
| 259 | + $this->addQueryCompatibleInputMiddleware($this->api); | |
| 260 | + $this->addQueryModeHeader(); | |
| 261 | + } | |
| 203 | 262 | if (isset($args['with_resolved'])) { |
| 204 | 263 | $args['with_resolved']($config); |
| 205 | 264 | } |
| 265 | + $this->addUserAgentMiddleware($config); | |
| 206 | 266 | } |
| 207 | 267 | public function getHandlerList() |
| 208 | 268 | { |
| 209 | 269 | return $this->handlerList; |
| @@ -209,9 +269,9 @@ | ||
| 209 | 269 | return $this->handlerList; |
| 210 | 270 | } |
| 211 | 271 | public function getConfig($option = null) |
| 212 | 272 | { |
| 213 | - return $option === null ? $this->config : (isset($this->config[$option]) ? $this->config[$option] : null); | |
| 273 | + return $option === null ? $this->config : $this->config[$option] ?? null; | |
| 214 | 274 | } |
| 215 | 275 | public function getCredentials() |
| 216 | 276 | { |
| 217 | 277 | $fn = $this->credentialProvider; |
| @@ -216,8 +276,13 @@ | ||
| 216 | 276 | { |
| 217 | 277 | $fn = $this->credentialProvider; |
| 218 | 278 | return $fn(); |
| 219 | 279 | } |
| 280 | + public function getToken() | |
| 281 | + { | |
| 282 | + $fn = $this->tokenProvider; | |
| 283 | + return $fn(); | |
| 284 | + } | |
| 220 | 285 | public function getEndpoint() |
| 221 | 286 | { |
| 222 | 287 | return $this->endpoint; |
| 223 | 288 | } |
| @@ -244,8 +309,32 @@ | ||
| 244 | 309 | $args['@http'] += $this->defaultRequestOptions; |
| 245 | 310 | } |
| 246 | 311 | return new Command($name, $args, clone $this->getHandlerList()); |
| 247 | 312 | } |
| 313 | + public function getEndpointProvider() | |
| 314 | + { | |
| 315 | + return $this->endpointProvider; | |
| 316 | + } | |
| 317 | + /** | |
| 318 | + * Provides the set of service context parameter | |
| 319 | + * key-value pairs used for endpoint resolution. | |
| 320 | + * | |
| 321 | + * @return array | |
| 322 | + */ | |
| 323 | + public function getClientContextParams() | |
| 324 | + { | |
| 325 | + return $this->clientContextParams; | |
| 326 | + } | |
| 327 | + /** | |
| 328 | + * Provides the set of built-in keys and values | |
| 329 | + * used for endpoint resolution | |
| 330 | + * | |
| 331 | + * @return array | |
| 332 | + */ | |
| 333 | + public function getClientBuiltIns() | |
| 334 | + { | |
| 335 | + return $this->clientBuiltIns; | |
| 336 | + } | |
| 248 | 337 | public function __sleep() |
| 249 | 338 | { |
| 250 | 339 | throw new \RuntimeException('Instances of ' . static::class . ' cannot be serialized'); |
| 251 | 340 | } |
| @@ -267,9 +356,9 @@ | ||
| 267 | 356 | private function parseClass() |
| 268 | 357 | { |
| 269 | 358 | $klass = \get_class($this); |
| 270 | 359 | if ($klass === __CLASS__) { |
| 271 | - return ['', 'Dudlewebs\\WPMCS\\s3\\Aws\\Exception\\AwsException']; | |
| 360 | + return ['', AwsException::class]; | |
| 272 | 361 | } |
| 273 | 362 | $service = \substr($klass, \strrpos($klass, '\\') + 1, -6); |
| 274 | 363 | return [\strtolower($service), "Dudlewebs\\WPMCS\\s3\\Aws\\{$service}\\Exception\\{$service}Exception"]; |
| 275 | 364 | } |
| @@ -286,40 +375,74 @@ | ||
| 286 | 375 | if (!isset($args['endpoint'])) { |
| 287 | 376 | $list->appendBuild(EndpointDiscoveryMiddleware::wrap($this, $args, $config['endpoint_discovery']), 'EndpointDiscoveryMiddleware'); |
| 288 | 377 | } |
| 289 | 378 | } |
| 290 | - private function addSignatureMiddleware() | |
| 379 | + private function addSignatureMiddleware(array $args) | |
| 291 | 380 | { |
| 292 | 381 | $api = $this->getApi(); |
| 293 | 382 | $provider = $this->signatureProvider; |
| 294 | - $version = $this->config['signature_version']; | |
| 383 | + $signatureVersion = $this->config['signature_version']; | |
| 295 | 384 | $name = $this->config['signing_name']; |
| 296 | 385 | $region = $this->config['signing_region']; |
| 297 | - $resolver = static function (CommandInterface $c) use($api, $provider, $name, $region, $version) { | |
| 298 | - if (!empty($c['@context']['signing_region'])) { | |
| 299 | - $region = $c['@context']['signing_region']; | |
| 386 | + $signingRegionSet = $this->signingRegionSet; | |
| 387 | + if (isset($args['signature_version']) || isset($this->config['configured_signature_version'])) { | |
| 388 | + $configuredSignatureVersion = \true; | |
| 389 | + } else { | |
| 390 | + $configuredSignatureVersion = \false; | |
| 391 | + } | |
| 392 | + $resolver = static function (CommandInterface $command) use($api, $provider, $name, $region, $signatureVersion, $configuredSignatureVersion, $signingRegionSet) { | |
| 393 | + if (!$configuredSignatureVersion) { | |
| 394 | + if (!empty($command['@context']['signing_region'])) { | |
| 395 | + $region = $command['@context']['signing_region']; | |
| 396 | + } | |
| 397 | + if (!empty($command['@context']['signing_service'])) { | |
| 398 | + $name = $command['@context']['signing_service']; | |
| 399 | + } | |
| 400 | + if (!empty($command['@context']['signature_version'])) { | |
| 401 | + $signatureVersion = $command['@context']['signature_version']; | |
| 402 | + } | |
| 403 | + $authType = $api->getOperation($command->getName())['authtype']; | |
| 404 | + switch ($authType) { | |
| 405 | + case 'none': | |
| 406 | + $signatureVersion = 'anonymous'; | |
| 407 | + break; | |
| 408 | + case 'v4-unsigned-body': | |
| 409 | + $signatureVersion = 'v4-unsigned-body'; | |
| 410 | + break; | |
| 411 | + case 'bearer': | |
| 412 | + $signatureVersion = 'bearer'; | |
| 413 | + break; | |
| 414 | + } | |
| 300 | 415 | } |
| 301 | - if (!empty($c['@context']['signing_service'])) { | |
| 302 | - $name = $c['@context']['signing_service']; | |
| 416 | + if ($signatureVersion === 'v4a') { | |
| 417 | + $commandSigningRegionSet = !empty($command['@context']['signing_region_set']) ? \implode(', ', $command['@context']['signing_region_set']) : null; | |
| 418 | + $region = $signingRegionSet ?? $commandSigningRegionSet ?? $region; | |
| 303 | 419 | } |
| 304 | - $authType = $api->getOperation($c->getName())['authtype']; | |
| 305 | - switch ($authType) { | |
| 306 | - case 'none': | |
| 307 | - $version = 'anonymous'; | |
| 308 | - break; | |
| 309 | - case 'v4-unsigned-body': | |
| 310 | - $version = 'v4-unsigned-body'; | |
| 311 | - break; | |
| 312 | - } | |
| 313 | - if (isset($c['@context']['signature_version'])) { | |
| 314 | - if ($c['@context']['signature_version'] == 'v4a') { | |
| 315 | - $version = 'v4a'; | |
| 316 | - } | |
| 317 | - } | |
| 318 | - return SignatureProvider::resolve($provider, $version, $name, $region); | |
| 420 | + // Capture signature metric | |
| 421 | + $command->getMetricsBuilder()->identifyMetricByValueAndAppend('signature', $signatureVersion); | |
| 422 | + return SignatureProvider::resolve($provider, $signatureVersion, $name, $region); | |
| 319 | 423 | }; |
| 320 | - $this->handlerList->appendSign(Middleware::signer($this->credentialProvider, $resolver), 'signer'); | |
| 424 | + $this->handlerList->appendSign(Middleware::signer($this->credentialProvider, $resolver, $this->tokenProvider, $this->getConfig()), 'signer'); | |
| 321 | 425 | } |
| 426 | + private function addRequestCompressionMiddleware($config) | |
| 427 | + { | |
| 428 | + if (empty($config['disable_request_compression'])) { | |
| 429 | + $list = $this->getHandlerList(); | |
| 430 | + $list->appendBuild(RequestCompressionMiddleware::wrap($config), 'request-compression'); | |
| 431 | + } | |
| 432 | + } | |
| 433 | + private function addQueryCompatibleInputMiddleware(Service $api) | |
| 434 | + { | |
| 435 | + $list = $this->getHandlerList(); | |
| 436 | + $list->appendValidate(QueryCompatibleInputMiddleware::wrap($api), 'query-compatible-input'); | |
| 437 | + } | |
| 438 | + private function addQueryModeHeader() : void | |
| 439 | + { | |
| 440 | + $list = $this->getHandlerList(); | |
| 441 | + $list->appendBuild(Middleware::mapRequest(function (RequestInterface $r) { | |
| 442 | + return $r->withHeader('x-amzn-query-mode', "true"); | |
| 443 | + }), 'x-amzn-query-mode-header'); | |
| 444 | + } | |
| 322 | 445 | private function addInvocationId() |
| 323 | 446 | { |
| 324 | 447 | // Add invocation id to each request |
| 325 | 448 | $this->handlerList->prependSign(Middleware::invocationId(), 'invocation-id'); |
| @@ -348,9 +471,122 @@ | ||
| 348 | 471 | // Add recursion detection header to requests |
| 349 | 472 | // originating in supported Lambda runtimes |
| 350 | 473 | $this->handlerList->appendBuild(Middleware::recursionDetection(), 'recursion-detection'); |
| 351 | 474 | } |
| 475 | + private function addAuthSelectionMiddleware(array $args) | |
| 476 | + { | |
| 477 | + $list = $this->getHandlerList(); | |
| 478 | + $list->prependBuild(AuthSelectionMiddleware::wrap($this->authSchemeResolver, $this->getApi(), $args['auth_scheme_preference'] ?? null), 'auth-selection'); | |
| 479 | + } | |
| 480 | + private function addEndpointV2Middleware() | |
| 481 | + { | |
| 482 | + $list = $this->getHandlerList(); | |
| 483 | + $endpointArgs = $this->getEndpointProviderArgs(); | |
| 484 | + $list->prependBuild(EndpointV2Middleware::wrap($this->endpointProvider, $this->getApi(), $endpointArgs, $this->credentialProvider), 'endpoint-resolution'); | |
| 485 | + } | |
| 352 | 486 | /** |
| 487 | + * Appends the user agent middleware. | |
| 488 | + * This middleware MUST be appended after the | |
| 489 | + * signature middleware `addSignatureMiddleware`, | |
| 490 | + * so that metrics around signatures are properly | |
| 491 | + * captured. | |
| 492 | + * | |
| 493 | + * @param $args | |
| 494 | + * @return void | |
| 495 | + */ | |
| 496 | + private function addUserAgentMiddleware($args) | |
| 497 | + { | |
| 498 | + $this->getHandlerList()->appendSign(UserAgentMiddleware::wrap($args), 'user-agent'); | |
| 499 | + } | |
| 500 | + /** | |
| 501 | + * Retrieves client context param definition from service model, | |
| 502 | + * creates mapping of client context param names with client-provided | |
| 503 | + * values. | |
| 504 | + * | |
| 505 | + * @return array | |
| 506 | + */ | |
| 507 | + private function setClientContextParams($args) | |
| 508 | + { | |
| 509 | + $api = $this->getApi(); | |
| 510 | + $resolvedParams = []; | |
| 511 | + if (!empty($paramDefinitions = $api->getClientContextParams())) { | |
| 512 | + foreach ($paramDefinitions as $paramName => $paramValue) { | |
| 513 | + if (isset($args[$paramName])) { | |
| 514 | + $resolvedParams[$paramName] = $args[$paramName]; | |
| 515 | + } | |
| 516 | + } | |
| 517 | + } | |
| 518 | + return $resolvedParams; | |
| 519 | + } | |
| 520 | + /** | |
| 521 | + * Retrieves and sets default values used for endpoint resolution. | |
| 522 | + */ | |
| 523 | + private function setClientBuiltIns($args, $resolvedConfig) | |
| 524 | + { | |
| 525 | + $builtIns = []; | |
| 526 | + $config = $resolvedConfig['config']; | |
| 527 | + $service = $args['service']; | |
| 528 | + $builtIns['SDK::Endpoint'] = null; | |
| 529 | + if (!empty($args['endpoint'])) { | |
| 530 | + $builtIns['SDK::Endpoint'] = $args['endpoint']; | |
| 531 | + } elseif (isset($config['configured_endpoint_url'])) { | |
| 532 | + $builtIns['SDK::Endpoint'] = (string) $this->getEndpoint(); | |
| 533 | + } | |
| 534 | + $builtIns['AWS::Region'] = $this->getRegion(); | |
| 535 | + $builtIns['AWS::UseFIPS'] = $config['use_fips_endpoint']->isUseFipsEndpoint(); | |
| 536 | + $builtIns['AWS::UseDualStack'] = $config['use_dual_stack_endpoint']->isUseDualstackEndpoint(); | |
| 537 | + if ($service === 's3' || $service === 's3control') { | |
| 538 | + $builtIns['AWS::S3::UseArnRegion'] = $config['use_arn_region']->isUseArnRegion(); | |
| 539 | + } | |
| 540 | + if ($service === 's3') { | |
| 541 | + $builtIns['AWS::S3::UseArnRegion'] = $config['use_arn_region']->isUseArnRegion(); | |
| 542 | + $builtIns['AWS::S3::Accelerate'] = $config['use_accelerate_endpoint']; | |
| 543 | + $builtIns['AWS::S3::ForcePathStyle'] = $config['use_path_style_endpoint']; | |
| 544 | + $builtIns['AWS::S3::DisableMultiRegionAccessPoints'] = $config['disable_multiregion_access_points']; | |
| 545 | + } | |
| 546 | + $builtIns['AWS::Auth::AccountIdEndpointMode'] = $resolvedConfig['account_id_endpoint_mode']; | |
| 547 | + $this->clientBuiltIns += $builtIns; | |
| 548 | + } | |
| 549 | + /** | |
| 550 | + * Retrieves arguments to be used in endpoint resolution. | |
| 551 | + * | |
| 552 | + * @return array | |
| 553 | + */ | |
| 554 | + public function getEndpointProviderArgs() | |
| 555 | + { | |
| 556 | + return $this->normalizeEndpointProviderArgs(); | |
| 557 | + } | |
| 558 | + /** | |
| 559 | + * Combines built-in and client context parameter values in | |
| 560 | + * order of specificity. Client context parameter values supersede | |
| 561 | + * built-in values. | |
| 562 | + * | |
| 563 | + * @return array | |
| 564 | + */ | |
| 565 | + private function normalizeEndpointProviderArgs() | |
| 566 | + { | |
| 567 | + $normalizedBuiltIns = []; | |
| 568 | + foreach ($this->clientBuiltIns as $name => $value) { | |
| 569 | + $normalizedName = \explode('::', $name); | |
| 570 | + $normalizedName = $normalizedName[\count($normalizedName) - 1]; | |
| 571 | + $normalizedBuiltIns[$normalizedName] = $value; | |
| 572 | + } | |
| 573 | + return \array_merge($normalizedBuiltIns, $this->getClientContextParams()); | |
| 574 | + } | |
| 575 | + protected function isUseEndpointV2() | |
| 576 | + { | |
| 577 | + return $this->endpointProvider instanceof EndpointProviderV2; | |
| 578 | + } | |
| 579 | + public static function emitDeprecationWarning() | |
| 580 | + { | |
| 581 | + \trigger_error("This method is deprecated. It will be removed in an upcoming release.", \E_USER_DEPRECATED); | |
| 582 | + $phpVersion = \PHP_VERSION_ID; | |
| 583 | + if ($phpVersion < 70205) { | |
| 584 | + $phpVersionString = \phpversion(); | |
| 585 | + @\trigger_error("This installation of the SDK is using PHP version" . " {$phpVersionString}, which will be deprecated on August" . " 15th, 2023. Please upgrade your PHP version to a minimum of" . " 7.2.5 before then to continue receiving updates to the AWS" . " SDK for PHP. To disable this warning, set" . " suppress_php_deprecation_warning to true on the client constructor" . " or set the environment variable AWS_SUPPRESS_PHP_DEPRECATION_WARNING" . " to true.", \E_USER_DEPRECATED); | |
| 586 | + } | |
| 587 | + } | |
| 588 | + /** | |
| 353 | 589 | * Returns a service model and doc model with any necessary changes |
| 354 | 590 | * applied. |
| 355 | 591 | * |
| 356 | 592 | * @param array $api Array of service data being documented. |
| @@ -363,9 +599,9 @@ | ||
| 363 | 599 | */ |
| 364 | 600 | public static function applyDocFilters(array $api, array $docs) |
| 365 | 601 | { |
| 366 | 602 | $aliases = \Dudlewebs\WPMCS\s3\Aws\load_compiled_json(__DIR__ . '/data/aliases.json'); |
| 367 | - $serviceId = $api['metadata']['serviceId']; | |
| 603 | + $serviceId = $api['metadata']['serviceId'] ?? ''; | |
| 368 | 604 | $version = $api['metadata']['apiVersion']; |
| 369 | 605 | // Replace names for any operations with SDK aliases |
| 370 | 606 | if (!empty($aliases['operations'][$serviceId][$version])) { |
| 371 | 607 | foreach ($aliases['operations'][$serviceId][$version] as $op => $alias) { |