← All changes
|
includes/sdk/google/google/cloud-storage/src/StorageClient.php
+142
-31
1.2.13
→
1.4.1
View file →
| @@ -14,22 +14,22 @@ | ||
| 14 | 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | 15 | * See the License for the specific language governing permissions and |
| 16 | 16 | * limitations under the License. |
| 17 | 17 | */ |
| 18 | -namespace Dudlewebs\WPMCS\Google\Cloud\Storage; | |
| 18 | +namespace Dudlewebs\WPMCS\GCP\Google\Cloud\Storage; | |
| 19 | 19 | |
| 20 | -use Dudlewebs\WPMCS\Google\Auth\FetchAuthTokenInterface; | |
| 21 | -use Dudlewebs\WPMCS\Google\Cloud\Core\ArrayTrait; | |
| 22 | -use Dudlewebs\WPMCS\Google\Cloud\Core\ClientTrait; | |
| 23 | -use Dudlewebs\WPMCS\Google\Cloud\Core\Exception\GoogleException; | |
| 24 | -use Dudlewebs\WPMCS\Google\Cloud\Core\Iterator\ItemIterator; | |
| 25 | -use Dudlewebs\WPMCS\Google\Cloud\Core\Iterator\PageIterator; | |
| 26 | -use Dudlewebs\WPMCS\Google\Cloud\Core\Timestamp; | |
| 27 | -use Dudlewebs\WPMCS\Google\Cloud\Core\Upload\SignedUrlUploader; | |
| 28 | -use Dudlewebs\WPMCS\Google\Cloud\Storage\Connection\ConnectionInterface; | |
| 29 | -use Dudlewebs\WPMCS\Google\Cloud\Storage\Connection\Rest; | |
| 30 | -use Dudlewebs\WPMCS\Psr\Cache\CacheItemPoolInterface; | |
| 31 | -use Dudlewebs\WPMCS\Psr\Http\Message\StreamInterface; | |
| 20 | +use Dudlewebs\WPMCS\GCP\Google\Auth\FetchAuthTokenInterface; | |
| 21 | +use Dudlewebs\WPMCS\GCP\Google\Cloud\Core\ArrayTrait; | |
| 22 | +use Dudlewebs\WPMCS\GCP\Google\Cloud\Core\ClientTrait; | |
| 23 | +use Dudlewebs\WPMCS\GCP\Google\Cloud\Core\Exception\GoogleException; | |
| 24 | +use Dudlewebs\WPMCS\GCP\Google\Cloud\Core\Iterator\ItemIterator; | |
| 25 | +use Dudlewebs\WPMCS\GCP\Google\Cloud\Core\Iterator\PageIterator; | |
| 26 | +use Dudlewebs\WPMCS\GCP\Google\Cloud\Core\Timestamp; | |
| 27 | +use Dudlewebs\WPMCS\GCP\Google\Cloud\Core\Upload\SignedUrlUploader; | |
| 28 | +use Dudlewebs\WPMCS\GCP\Google\Cloud\Storage\Connection\ConnectionInterface; | |
| 29 | +use Dudlewebs\WPMCS\GCP\Google\Cloud\Storage\Connection\Rest; | |
| 30 | +use Dudlewebs\WPMCS\GCP\Psr\Cache\CacheItemPoolInterface; | |
| 31 | +use Dudlewebs\WPMCS\GCP\Psr\Http\Message\StreamInterface; | |
| 32 | 32 | /** |
| 33 | 33 | * Google Cloud Storage allows you to store and retrieve data on Google's |
| 34 | 34 | * infrastructure. Find more information at the |
| 35 | 35 | * [Google Cloud Storage API docs](https://developers.google.com/storage). |
| @@ -44,9 +44,9 @@ | ||
| 44 | 44 | class StorageClient |
| 45 | 45 | { |
| 46 | 46 | use ArrayTrait; |
| 47 | 47 | use ClientTrait; |
| 48 | - const VERSION = '1.39.0'; | |
| 48 | + const VERSION = '1.49.2'; | |
| 49 | 49 | const FULL_CONTROL_SCOPE = 'https://www.googleapis.com/auth/devstorage.full_control'; |
| 50 | 50 | const READ_ONLY_SCOPE = 'https://www.googleapis.com/auth/devstorage.read_only'; |
| 51 | 51 | const READ_WRITE_SCOPE = 'https://www.googleapis.com/auth/devstorage.read_write'; |
| 52 | 52 | /** |
| @@ -90,18 +90,73 @@ | ||
| 90 | 90 | * @type FetchAuthTokenInterface $credentialsFetcher A credentials |
| 91 | 91 | * fetcher instance. |
| 92 | 92 | * @type callable $httpHandler A handler used to deliver Psr7 requests. |
| 93 | 93 | * Only valid for requests sent over REST. |
| 94 | - * @type array $keyFile The contents of the service account credentials | |
| 95 | - * .json file retrieved from the Google Developer's Console. | |
| 96 | - * Ex: `json_decode(file_get_contents($path), true)`. | |
| 97 | - * @type string $keyFilePath The full path to your service account | |
| 98 | - * credentials .json file retrieved from the Google Developers | |
| 99 | - * Console. | |
| 94 | + * @type array $keyFile [DEPRECATED] | |
| 95 | + * This option is being deprecated because of a potential security risk. | |
| 96 | + * This option does not validate the credential configuration. The security | |
| 97 | + * risk occurs when a credential configuration is accepted from a source | |
| 98 | + * that is not under your control and used without validation on your side. | |
| 99 | + * If you know that you will be loading credential configurations of a | |
| 100 | + * specific type, it is recommended to create the credentials directly and | |
| 101 | + * configure them using the `credentialsFetcher` option instead. | |
| 102 | + * ``` | |
| 103 | + * use Google\Auth\Credentials\ServiceAccountCredentials; | |
| 104 | + * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); | |
| 105 | + * $creds = new StorageClient(['credentialsFetcher' => $creds]); | |
| 106 | + * ``` | |
| 107 | + * This will ensure that an unexpected credential type with potential for | |
| 108 | + * malicious intent is not loaded unintentionally. You might still have to do | |
| 109 | + * validation for certain credential types. | |
| 110 | + * If you are loading your credential configuration from an untrusted source and have | |
| 111 | + * not mitigated the risks (e.g. by validating the configuration yourself), make | |
| 112 | + * these changes as soon as possible to prevent security risks to your environment. | |
| 113 | + * Regardless of the method used, it is always your responsibility to validate | |
| 114 | + * configurations received from external sources. | |
| 115 | + * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials | |
| 116 | + * @type string $keyFilePath [DEPRECATED] | |
| 117 | + * This option is being deprecated because of a potential security risk. | |
| 118 | + * This option does not validate the credential configuration. The security | |
| 119 | + * risk occurs when a credential configuration is accepted from a source | |
| 120 | + * that is not under your control and used without validation on your side. | |
| 121 | + * If you know that you will be loading credential configurations of a | |
| 122 | + * specific type, it is recommended to create the credentials directly and | |
| 123 | + * configure them using the `credentialsFetcher` option instead. | |
| 124 | + * ``` | |
| 125 | + * use Google\Auth\Credentials\ServiceAccountCredentials; | |
| 126 | + * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); | |
| 127 | + * $creds = new StorageClient(['credentialsFetcher' => $creds]); | |
| 128 | + * ``` | |
| 129 | + * This will ensure that an unexpected credential type with potential for | |
| 130 | + * malicious intent is not loaded unintentionally. You might still have to do | |
| 131 | + * validation for certain credential types. | |
| 132 | + * If you are loading your credential configuration from an untrusted source and have | |
| 133 | + * not mitigated the risks (e.g. by validating the configuration yourself), make | |
| 134 | + * these changes as soon as possible to prevent security risks to your environment. | |
| 135 | + * Regardless of the method used, it is always your responsibility to validate | |
| 136 | + * configurations received from external sources. | |
| 137 | + * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials | |
| 100 | 138 | * @type float $requestTimeout Seconds to wait before timing out the |
| 101 | 139 | * request. **Defaults to** `0` with REST and `60` with gRPC. |
| 102 | 140 | * @type int $retries Number of retries for a failed request. |
| 103 | 141 | * **Defaults to** `3`. |
| 142 | + * @type string $retryStrategy Retry strategy to signify that we never | |
| 143 | + * want to retry an operation even if the error is retryable. | |
| 144 | + * **Defaults to** `StorageClient::RETRY_IDEMPOTENT`. | |
| 145 | + * @type callable $restDelayFunction Executes a delay, defaults to | |
| 146 | + * utilizing `usleep`. Function signature should match: | |
| 147 | + * `function (int $delay) : void`. | |
| 148 | + * @type callable $restCalcDelayFunction Sets the conditions for | |
| 149 | + * determining how long to wait between attempts to retry. Function | |
| 150 | + * signature should match: `function (int $attempt) : int`. | |
| 151 | + * @type callable $restRetryFunction Sets the conditions for whether or | |
| 152 | + * not a request should attempt to retry. Function signature should | |
| 153 | + * match: `function (\Exception $ex) : bool`. | |
| 154 | + * @type callable $restRetryListener Runs after the restRetryFunction. | |
| 155 | + * This might be used to simply consume the exception and | |
| 156 | + * $arguments b/w retries. This returns the new $arguments thus | |
| 157 | + * allowing modification on demand for $arguments. For ex: | |
| 158 | + * changing the headers in b/w retries. | |
| 104 | 159 | * @type array $scopes Scopes to be used for the request. |
| 105 | 160 | * @type string $quotaProject Specifies a user project to bill for |
| 106 | 161 | * access charges associated with the request. |
| 107 | 162 | * } |
| @@ -134,18 +189,28 @@ | ||
| 134 | 189 | * @param string|bool $userProject If true, the current Project ID |
| 135 | 190 | * will be used. If a string, that string will be used as the |
| 136 | 191 | * userProject argument, and that project will be billed for the |
| 137 | 192 | * request. **Defaults to** `false`. |
| 193 | + * @param array $options [optional] { | |
| 194 | + * Configuration Options. | |
| 195 | + * | |
| 196 | + * @type bool $softDeleted If set to true, only soft-deleted bucket versions | |
| 197 | + * are listed as distinct results in order of bucket name and generation | |
| 198 | + * number. The default value is false. | |
| 199 | + * @type string $generation If present, selects a specific soft-deleted version | |
| 200 | + * of this bucket instead of the live version. This parameter is required if | |
| 201 | + * softDeleted is set to true. | |
| 202 | + * } | |
| 138 | 203 | * @return Bucket |
| 139 | 204 | */ |
| 140 | - public function bucket($name, $userProject = \false) | |
| 205 | + public function bucket($name, $userProject = \false, array $options = []) | |
| 141 | 206 | { |
| 142 | 207 | if (!$userProject) { |
| 143 | 208 | $userProject = null; |
| 144 | - } elseif (!is_string($userProject)) { | |
| 209 | + } elseif (!\is_string($userProject)) { | |
| 145 | 210 | $userProject = $this->projectId; |
| 146 | 211 | } |
| 147 | - return new Bucket($this->connection, $name, ['requesterProjectId' => $userProject]); | |
| 212 | + return new Bucket($this->connection, $name, $options + ['requesterProjectId' => $userProject]); | |
| 148 | 213 | } |
| 149 | 214 | /** |
| 150 | 215 | * Fetches all buckets in the project. |
| 151 | 216 | * |
| @@ -182,15 +247,23 @@ | ||
| 182 | 247 | * @type string $fields Selector which will cause the response to only |
| 183 | 248 | * return the specified fields. |
| 184 | 249 | * @type string $userProject If set, this is the ID of the project which |
| 185 | 250 | * will be billed for the request. |
| 251 | + * @type bool $softDeleted If set to true, only soft-deleted bucket versions | |
| 252 | + * are listed as distinct results in order of bucket name and generation | |
| 253 | + * number. The default value is false. | |
| 186 | 254 | * @type bool $bucketUserProject If true, each returned instance will |
| 187 | 255 | * have `$userProject` set to the value of `$options.userProject`. |
| 188 | 256 | * If false, `$options.userProject` will be used ONLY for the |
| 189 | 257 | * listBuckets operation. If `$options.userProject` is not set, |
| 190 | 258 | * this option has no effect. **Defaults to** `true`. |
| 259 | + * @type bool $returnPartialSuccess If true, the returned iterator will contain an | |
| 260 | + * `unreachable` property with a list of buckets that were not retrieved. | |
| 261 | + * **Note:** If set to false (default) and unreachable buckets are found, | |
| 262 | + * the operation will throw an exception. | |
| 263 | + * | |
| 191 | 264 | * } |
| 192 | - * @return ItemIterator<Bucket> | |
| 265 | + * @return BucketIterator<Bucket> | |
| 193 | 266 | * @throws GoogleException When a project ID has not been detected. |
| 194 | 267 | */ |
| 195 | 268 | public function buckets(array $options = []) |
| 196 | 269 | { |
| @@ -195,16 +268,52 @@ | ||
| 195 | 268 | public function buckets(array $options = []) |
| 196 | 269 | { |
| 197 | 270 | $this->requireProjectId(); |
| 198 | 271 | $resultLimit = $this->pluck('resultLimit', $options, \false); |
| 199 | - $bucketUserProject = $this->pluck('bucketUserProject', $options, \false); | |
| 200 | - $bucketUserProject = !is_null($bucketUserProject) ? $bucketUserProject : \true; | |
| 201 | - $userProject = isset($options['userProject']) && $bucketUserProject ? $options['userProject'] : null; | |
| 202 | - return new ItemIterator(new PageIterator(function (array $bucket) use ($userProject) { | |
| 272 | + $bucketUserProject = $this->pluck('bucketUserProject', $options, null) ?? \true; | |
| 273 | + $userProject = $bucketUserProject ? $options['userProject'] ?? null : null; | |
| 274 | + $unreachable = new \ArrayObject(); | |
| 275 | + $apiCall = [$this->connection, 'listBuckets']; | |
| 276 | + $callDelegate = function (array $args) use($apiCall, $unreachable) { | |
| 277 | + $response = \call_user_func($apiCall, $args); | |
| 278 | + if (isset($response['unreachable']) && \is_array($response['unreachable'])) { | |
| 279 | + $current = $unreachable->getArrayCopy(); | |
| 280 | + $updated = \array_unique(\array_merge($current, $response['unreachable'])); | |
| 281 | + $unreachable->exchangeArray($updated); | |
| 282 | + } | |
| 283 | + return $response; | |
| 284 | + }; | |
| 285 | + // Return the new BucketIterator with the wrapped unreachable bucket | |
| 286 | + return new BucketIterator(new PageIterator(function (array $bucket) use($userProject) { | |
| 203 | 287 | return new Bucket($this->connection, $bucket['name'], $bucket + ['requesterProjectId' => $userProject]); |
| 204 | - }, [$this->connection, 'listBuckets'], $options + ['project' => $this->projectId], ['resultLimit' => $resultLimit])); | |
| 288 | + }, $callDelegate, $options + ['project' => $this->projectId], ['resultLimit' => $resultLimit]), $unreachable); | |
| 205 | 289 | } |
| 206 | 290 | /** |
| 291 | + * Restores a soft-deleted bucket. | |
| 292 | + * | |
| 293 | + * Example: | |
| 294 | + * ``` | |
| 295 | + * $bucket = $storage->bucket->restore('my-bucket'); | |
| 296 | + * ``` | |
| 297 | + * | |
| 298 | + * @param string $name The name of the bucket to restore. | |
| 299 | + * @param string $generation The specific version of the bucket to be restored. | |
| 300 | + * @param array $options [optional] { | |
| 301 | + * Configuration Options. | |
| 302 | + * | |
| 303 | + * @type string $projection Determines which properties to return. May | |
| 304 | + * be either `"full"` or `"noAcl"`. **Defaults to** `"noAcl"`, | |
| 305 | + * unless the bucket resource specifies acl or defaultObjectAcl | |
| 306 | + * properties, when it defaults to `"full"`. | |
| 307 | + * } | |
| 308 | + * @return Bucket | |
| 309 | + */ | |
| 310 | + public function restore(string $name, string $generation, array $options = []) | |
| 311 | + { | |
| 312 | + $res = $this->connection->restoreBucket(['bucket' => $name, 'generation' => $generation] + $options); | |
| 313 | + return new Bucket($this->connection, $name); | |
| 314 | + } | |
| 315 | + /** | |
| 207 | 316 | * Create a bucket. Bucket names must be unique as Cloud Storage uses a flat |
| 208 | 317 | * namespace. For more information please see |
| 209 | 318 | * [bucket name requirements](https://cloud.google.com/storage/docs/naming#requirements) |
| 210 | 319 | * |
| @@ -256,8 +365,10 @@ | ||
| 256 | 365 | * a dual-region, the `customPlacementConfig` property should be |
| 257 | 366 | * set in conjunction. For more information, see |
| 258 | 367 | * [Bucket Locations](https://cloud.google.com/storage/docs/locations). |
| 259 | 368 | * **Defaults to** `"US"`. |
| 369 | + * @type array $hierarchicalNamespace The hierarchical namespace configuration | |
| 370 | + * on this bucket. | |
| 260 | 371 | * @type array $customPlacementConfig The bucket's dual regions. For more |
| 261 | 372 | * information, see |
| 262 | 373 | * [Bucket Locations](https://cloud.google.com/storage/docs/locations). |
| 263 | 374 | * @type array $logging The bucket's logging configuration, which |
| @@ -338,9 +449,9 @@ | ||
| 338 | 449 | if (isset($options['lifecycle']) && $options['lifecycle'] instanceof Lifecycle) { |
| 339 | 450 | $options['lifecycle'] = $options['lifecycle']->toArray(); |
| 340 | 451 | } |
| 341 | 452 | $bucketUserProject = $this->pluck('bucketUserProject', $options, \false); |
| 342 | - $bucketUserProject = !is_null($bucketUserProject) ? $bucketUserProject : \true; | |
| 453 | + $bucketUserProject = !\is_null($bucketUserProject) ? $bucketUserProject : \true; | |
| 343 | 454 | $userProject = isset($options['userProject']) && $bucketUserProject ? $options['userProject'] : null; |
| 344 | 455 | $response = $this->connection->insertBucket($options + ['name' => $name, 'project' => $this->projectId]); |
| 345 | 456 | return new Bucket($this->connection, $name, $response + ['requesterProjectId' => $userProject]); |
| 346 | 457 | } |
| @@ -453,9 +564,9 @@ | ||
| 453 | 564 | if (!$options['projectId']) { |
| 454 | 565 | $this->requireProjectId(); |
| 455 | 566 | } |
| 456 | 567 | $resultLimit = $this->pluck('resultLimit', $options, \false); |
| 457 | - return new ItemIterator(new PageIterator(function (array $metadata) use ($options) { | |
| 568 | + return new ItemIterator(new PageIterator(function (array $metadata) use($options) { | |
| 458 | 569 | return $this->hmacKey($metadata['accessId'], $options['projectId'], $metadata); |
| 459 | 570 | }, [$this->connection, 'listHmacKeys'], $options, ['resultLimit' => $resultLimit])); |
| 460 | 571 | } |
| 461 | 572 | /** |