BlobRestProxy::uploadPageBlobAsync()   B
last analyzed

Complexity

Conditions 4
Paths 2

Size

Total Lines 102
Code Lines 66

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 66
c 0
b 0
f 0
nc 2
nop 4
dl 0
loc 102
rs 8.7418

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * LICENSE: The MIT License (the "License")
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 * https://github.com/azure/azure-storage-php/LICENSE
8
 *
9
 * Unless required by applicable law or agreed to in writing, software
10
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * See the License for the specific language governing permissions and
13
 * limitations under the License.
14
 *
15
 * PHP version 5
16
 *
17
 * @category  Microsoft
18
 * @package   MicrosoftAzure\Storage\Blob
19
 * @author    Azure Storage PHP SDK <[email protected]>
20
 * @copyright 2016 Microsoft Corporation
21
 * @license   https://github.com/azure/azure-storage-php/LICENSE
22
 * @link      https://github.com/azure/azure-storage-php
23
 */
24
25
namespace MicrosoftAzure\Storage\Blob;
26
27
use MicrosoftAzure\Storage\Common\Internal\ServiceRestTrait;
28
use MicrosoftAzure\Storage\Common\Internal\Http\HttpFormatter;
29
use MicrosoftAzure\Storage\Common\Internal\Utilities;
30
use MicrosoftAzure\Storage\Common\Internal\Resources;
31
use MicrosoftAzure\Storage\Common\Internal\Validate;
32
use MicrosoftAzure\Storage\Common\Internal\ServiceRestProxy;
33
use MicrosoftAzure\Storage\Common\LocationMode;
34
use MicrosoftAzure\Storage\Common\Models\Range;
35
use MicrosoftAzure\Storage\Blob\Internal\IBlob;
36
use MicrosoftAzure\Storage\Blob\Models\AppendBlockOptions;
37
use MicrosoftAzure\Storage\Blob\Models\AppendBlockResult;
38
use MicrosoftAzure\Storage\Blob\Models\BlobServiceOptions;
39
use MicrosoftAzure\Storage\Blob\Models\ListContainersOptions;
40
use MicrosoftAzure\Storage\Blob\Models\ListContainersResult;
41
use MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions;
42
use MicrosoftAzure\Storage\Blob\Models\GetContainerPropertiesResult;
43
use MicrosoftAzure\Storage\Blob\Models\GetContainerACLResult;
44
use MicrosoftAzure\Storage\Blob\Models\ListBlobsOptions;
45
use MicrosoftAzure\Storage\Blob\Models\ListBlobsResult;
46
use MicrosoftAzure\Storage\Blob\Models\BlobType;
47
use MicrosoftAzure\Storage\Blob\Models\Block;
48
use MicrosoftAzure\Storage\Blob\Models\CreateBlobOptions;
49
use MicrosoftAzure\Storage\Blob\Models\BlobProperties;
50
use MicrosoftAzure\Storage\Blob\Models\GetBlobPropertiesOptions;
51
use MicrosoftAzure\Storage\Blob\Models\GetBlobPropertiesResult;
52
use MicrosoftAzure\Storage\Blob\Models\SetBlobPropertiesOptions;
53
use MicrosoftAzure\Storage\Blob\Models\SetBlobPropertiesResult;
54
use MicrosoftAzure\Storage\Blob\Models\GetBlobMetadataOptions;
55
use MicrosoftAzure\Storage\Blob\Models\GetBlobMetadataResult;
56
use MicrosoftAzure\Storage\Blob\Models\SetBlobMetadataResult;
57
use MicrosoftAzure\Storage\Blob\Models\GetBlobOptions;
58
use MicrosoftAzure\Storage\Blob\Models\GetBlobResult;
59
use MicrosoftAzure\Storage\Blob\Models\DeleteBlobOptions;
60
use MicrosoftAzure\Storage\Blob\Models\LeaseMode;
61
use MicrosoftAzure\Storage\Blob\Models\LeaseResult;
62
use MicrosoftAzure\Storage\Blob\Models\CreateBlobPagesOptions;
63
use MicrosoftAzure\Storage\Blob\Models\CreateBlobPagesResult;
64
use MicrosoftAzure\Storage\Blob\Models\PageWriteOption;
65
use MicrosoftAzure\Storage\Blob\Models\ListPageBlobRangesOptions;
66
use MicrosoftAzure\Storage\Blob\Models\ListPageBlobRangesResult;
67
use MicrosoftAzure\Storage\Blob\Models\CreateBlobBlockOptions;
68
use MicrosoftAzure\Storage\Blob\Models\CommitBlobBlocksOptions;
69
use MicrosoftAzure\Storage\Blob\Models\BlockList;
70
use MicrosoftAzure\Storage\Blob\Models\ListBlobBlocksOptions;
71
use MicrosoftAzure\Storage\Blob\Models\ContainerACL;
72
use MicrosoftAzure\Storage\Blob\Models\ListBlobBlocksResult;
73
use MicrosoftAzure\Storage\Blob\Models\CopyBlobOptions;
74
use MicrosoftAzure\Storage\Blob\Models\CreateBlobSnapshotOptions;
75
use MicrosoftAzure\Storage\Blob\Models\CreateBlobSnapshotResult;
76
use MicrosoftAzure\Storage\Blob\Models\CopyBlobResult;
77
use MicrosoftAzure\Storage\Blob\Models\BreakLeaseResult;
78
use MicrosoftAzure\Storage\Blob\Models\PutBlockResult;
79
use MicrosoftAzure\Storage\Blob\Models\PutBlobResult;
80
use Psr\Http\Message\StreamInterface;
81
use GuzzleHttp\Promise\PromiseInterface;
82
use GuzzleHttp\Psr7;
83
84
/**
85
 * This class constructs HTTP requests and receive HTTP responses for blob
86
 * service layer.
87
 *
88
 * @category  Microsoft
89
 * @package   MicrosoftAzure\Storage\Blob
90
 * @author    Azure Storage PHP SDK <[email protected]>
91
 * @copyright 2016 Microsoft Corporation
92
 * @license   https://github.com/azure/azure-storage-php/LICENSE
93
 * @link      https://github.com/azure/azure-storage-php
94
 */
95
class BlobRestProxy extends ServiceRestProxy implements IBlob
96
{
97
    use ServiceRestTrait;
98
99
    private $_SingleBlobUploadThresholdInBytes = Resources::MB_IN_BYTES_32;
100
101
    /**
102
     * Get the value for SingleBlobUploadThresholdInBytes
103
     *
104
     * @return int
105
     */
106
    public function getSingleBlobUploadThresholdInBytes()
107
    {
108
        return $this->_SingleBlobUploadThresholdInBytes;
109
    }
110
111
    /**
112
     * Set the value for SingleBlobUploadThresholdInBytes, Max 64MB
113
     *
114
     * @param int $val The max size to send as a single blob block
115
     *
116
     * @return void
117
     */
118
    public function setSingleBlobUploadThresholdInBytes($val)
119
    {
120
        if ($val > Resources::MB_IN_BYTES_64) {
121
            // What should the proper action here be?
122
            $val = Resources::MB_IN_BYTES_64;
123
        } elseif ($val < 1) {
124
            // another spot that could use looking at
125
            $val = Resources::MB_IN_BYTES_32;
126
        }
127
        $this->_SingleBlobUploadThresholdInBytes = $val;
128
    }
129
130
    /**
131
     * Gets the copy blob source name with specified parameters.
132
     *
133
     * @param string                 $containerName The name of the container.
134
     * @param string                 $blobName      The name of the blob.
135
     * @param Models\CopyBlobOptions $options       The optional parameters.
136
     *
137
     * @return string
138
     */
139
    private function _getCopyBlobSourceName(
140
        $containerName,
141
        $blobName,
142
        Models\CopyBlobOptions $options
143
    ) {
144
        $sourceName = $this->_getBlobUrl($containerName, $blobName);
145
146
        if (!is_null($options->getSourceSnapshot())) {
0 ignored issues
show
introduced by
The condition is_null($options->getSourceSnapshot()) is always false.
Loading history...
147
            $sourceName .= '?snapshot=' . $options->getSourceSnapshot();
148
        }
149
150
        return $sourceName;
151
    }
152
    
153
    /**
154
     * Creates URI path for blob or container.
155
     *
156
     * @param string $container The container name.
157
     * @param string $blob      The blob name.
158
     *
159
     * @return string
160
     */
161
    private function _createPath($container, $blob = '')
162
    {
163
        if (empty($blob)) {
164
            if (!empty($container)) {
165
                return $container;
166
            } else {
167
                return '/' . $container;
168
            }
169
        } else {
170
            $encodedBlob = urlencode($blob);
171
            // Unencode the forward slashes to match what the server expects.
172
            $encodedBlob = str_replace('%2F', '/', $encodedBlob);
173
            // Unencode the backward slashes to match what the server expects.
174
            $encodedBlob = str_replace('%5C', '/', $encodedBlob);
175
            // Re-encode the spaces (encoded as space) to the % encoding.
176
            $encodedBlob = str_replace('+', '%20', $encodedBlob);
177
            // Empty container means accessing default container
178
            if (empty($container)) {
179
                return $encodedBlob;
180
            } else {
181
                return '/' . $container . '/' . $encodedBlob;
182
            }
183
        }
184
    }
185
    
186
    /**
187
     * Creates full URI to the given blob.
188
     *
189
     * @param string $container The container name.
190
     * @param string $blob      The blob name.
191
     *
192
     * @return string
193
     */
194
    private function _getBlobUrl($container, $blob)
195
    {
196
        $encodedBlob = $this->_createPath($container, $blob);
197
198
        return (string)($this->getPsrPrimaryUri()->withPath($encodedBlob));
199
    }
200
      
201
    /**
202
     * Helper method to create promise for getContainerProperties API call.
203
     *
204
     * @param string                    $container The container name.
205
     * @param Models\BlobServiceOptions $options   The optional parameters.
206
     * @param string                    $operation The operation string. Should be
207
     * 'metadata' to get metadata.
208
     *
209
     * @return \GuzzleHttp\Promise\PromiseInterface
210
     */
211
    private function _getContainerPropertiesAsyncImpl(
212
        $container,
213
        Models\BlobServiceOptions $options = null,
214
        $operation = null
215
    ) {
216
        Validate::isString($container, 'container');
217
        
218
        $method      = Resources::HTTP_GET;
219
        $headers     = array();
220
        $queryParams = array();
221
        $postParams  = array();
222
        $path        = $this->_createPath($container);
223
        
224
        if (is_null($options)) {
225
            $options = new BlobServiceOptions();
226
        }
227
        
228
        $this->addOptionalQueryParam(
229
            $queryParams,
230
            Resources::QP_REST_TYPE,
231
            'container'
232
        );
233
        $this->addOptionalQueryParam(
234
            $queryParams,
235
            Resources::QP_COMP,
236
            $operation
237
        );
238
239
        $this->addOptionalHeader(
240
            $headers,
241
            Resources::X_MS_LEASE_ID,
242
            $options->getLeaseId()
243
        );
244
        $this->addOptionalAccessConditionHeader(
245
            $headers,
246
            $options->getAccessConditions()
247
        );
248
        
249
        return $this->sendAsync(
250
            $method,
251
            $headers,
252
            $queryParams,
253
            $postParams,
254
            $path,
255
            Resources::STATUS_OK,
256
            Resources::EMPTY_STRING,
257
            $options
258
        )->then(function ($response) {
259
            $responseHeaders = HttpFormatter::formatHeaders($response->getHeaders());
260
            return GetContainerPropertiesResult::create($responseHeaders);
261
        }, null);
262
    }
263
    
264
    /**
265
     * Adds optional create blob headers.
266
     *
267
     * @param CreateBlobOptions $options The optional parameters.
268
     * @param array             $headers The HTTP request headers.
269
     *
270
     * @return array
271
     */
272
    private function _addCreateBlobOptionalHeaders(
273
        CreateBlobOptions $options,
274
        array $headers
275
    ) {
276
        $headers = $this->addOptionalAccessConditionHeader(
277
            $headers,
278
            $options->getAccessConditions()
279
        );
280
        
281
        $this->addOptionalHeader(
282
            $headers,
283
            Resources::X_MS_LEASE_ID,
284
            $options->getLeaseId()
285
        );
286
287
        $headers = $this->addMetadataHeaders(
288
            $headers,
289
            $options->getMetadata()
290
        );
291
292
        $contentType = $options->getContentType();
293
        if (is_null($contentType)) {
0 ignored issues
show
introduced by
The condition is_null($contentType) is always false.
Loading history...
294
            $contentType = Resources::BINARY_FILE_TYPE;
295
        }
296
297
        $this->addOptionalHeader(
298
            $headers,
299
            Resources::X_MS_BLOB_CONTENT_TYPE,
300
            $contentType
301
        );
302
        $this->addOptionalHeader(
303
            $headers,
304
            Resources::X_MS_BLOB_CONTENT_ENCODING,
305
            $options->getContentEncoding()
306
        );
307
        $this->addOptionalHeader(
308
            $headers,
309
            Resources::X_MS_BLOB_CONTENT_LANGUAGE,
310
            $options->getContentLanguage()
311
        );
312
        $this->addOptionalHeader(
313
            $headers,
314
            Resources::X_MS_BLOB_CONTENT_MD5,
315
            $options->getContentMD5()
316
        );
317
        $this->addOptionalHeader(
318
            $headers,
319
            Resources::X_MS_BLOB_CACHE_CONTROL,
320
            $options->getCacheControl()
321
        );
322
        $this->addOptionalHeader(
323
            $headers,
324
            Resources::X_MS_BLOB_CONTENT_DISPOSITION,
325
            $options->getContentDisposition()
326
        );
327
        $this->addOptionalHeader(
328
            $headers,
329
            Resources::CONTENT_TYPE,
330
            Resources::URL_ENCODED_CONTENT_TYPE
331
        );
332
        
333
        return $headers;
334
    }
335
    
336
    /**
337
     * Adds Range header to the headers array.
338
     *
339
     * @param array   $headers The HTTP request headers.
340
     * @param integer $start   The start byte.
341
     * @param integer $end     The end byte.
342
     *
343
     * @return array
344
     */
345
    private function _addOptionalRangeHeader(array $headers, $start, $end)
346
    {
347
        if (!is_null($start) || !is_null($end)) {
0 ignored issues
show
introduced by
The condition is_null($start) is always false.
Loading history...
348
            $range      = $start . '-' . $end;
349
            $rangeValue = 'bytes=' . $range;
350
            $this->addOptionalHeader($headers, Resources::RANGE, $rangeValue);
351
        }
352
        
353
        return $headers;
354
    }
355
356
    /**
357
     * Get the expected status code of a given lease action.
358
     *
359
     * @param  string $leaseAction The given lease action
360
     *
361
     * @return string
362
     */
363
    private static function getStatusCodeOfLeaseAction($leaseAction)
364
    {
365
        $statusCode = Resources::EMPTY_STRING;
0 ignored issues
show
Unused Code introduced by
The assignment to $statusCode is dead and can be removed.
Loading history...
366
        switch ($leaseAction) {
367
            case LeaseMode::ACQUIRE_ACTION:
368
                $statusCode = Resources::STATUS_CREATED;
369
                break;
370
            case LeaseMode::RENEW_ACTION:
371
                $statusCode = Resources::STATUS_OK;
372
                break;
373
            case LeaseMode::RELEASE_ACTION:
374
                $statusCode = Resources::STATUS_OK;
375
                break;
376
            case LeaseMode::BREAK_ACTION:
377
                $statusCode = Resources::STATUS_ACCEPTED;
378
                break;
379
            default:
380
                throw new \Exception(Resources::NOT_IMPLEMENTED_MSG);
381
        }
382
383
        return $statusCode;
384
    }
385
386
    /**
387
     * Creates promise that does the actual work for leasing a blob.
388
     *
389
     * @param string                    $leaseAction        Lease action string.
390
     * @param string                    $container          Container name.
391
     * @param string                    $blob               Blob to lease name.
392
     * @param string                    $leaseId            Existing lease id.
393
     * @param string                    $expectedStatusCode Expected status code.
394
     * @param Models\BlobServiceOptions $options            Optional parameters.
395
     * @param Models\AccessCondition    $accessCondition    Access conditions.
396
     *
397
     * @return \GuzzleHttp\Promise\PromiseInterface
398
     */
399
    private function _putLeaseAsyncImpl(
400
        $leaseAction,
401
        $container,
402
        $blob,
403
        $proposedLeaseId,
404
        $leaseDuration,
405
        $leaseId,
406
        $breakPeriod,
407
        $expectedStatusCode,
408
        Models\BlobServiceOptions $options,
409
        Models\AccessCondition $accessCondition = null
410
    ) {
411
        Validate::isString($blob, 'blob');
412
        Validate::isString($container, 'container');
413
        Validate::notNullOrEmpty($container, 'container');
414
        
415
        $method      = Resources::HTTP_PUT;
416
        $headers     = array();
417
        $queryParams = array();
418
        $postParams  = array();
419
        $path;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $path seems to be never defined.
Loading history...
420
421
        if (empty($blob)) {
422
            $path = $this->_createPath($container);
423
            $this->addOptionalQueryParam(
424
                $queryParams,
425
                Resources::QP_REST_TYPE,
426
                'container'
427
            );
428
        } else {
429
            $path = $this->_createPath($container, $blob);
430
        }
431
        $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'lease');
432
        $this->addOptionalQueryParam(
433
            $queryParams,
434
            Resources::QP_TIMEOUT,
435
            $options->getTimeout()
436
        );
437
        
438
        $this->addOptionalHeader($headers, Resources::X_MS_LEASE_ID, $leaseId);
439
        $this->addOptionalHeader(
440
            $headers,
441
            Resources::X_MS_LEASE_ACTION,
442
            $leaseAction
443
        );
444
        $this->addOptionalHeader(
445
            $headers,
446
            Resources::X_MS_LEASE_BREAK_PERIOD,
447
            $breakPeriod
448
        );
449
        $this->addOptionalHeader(
450
            $headers,
451
            Resources::X_MS_LEASE_DURATION,
452
            $leaseDuration
453
        );
454
        $this->addOptionalHeader(
455
            $headers,
456
            Resources::X_MS_PROPOSED_LEASE_ID,
457
            $proposedLeaseId
458
        );
459
        $this->addOptionalAccessConditionHeader($headers, $accessCondition);
0 ignored issues
show
Bug introduced by
It seems like $accessCondition can also be of type MicrosoftAzure\Storage\Blob\Models\AccessCondition; however, parameter $accessConditions of MicrosoftAzure\Storage\B...AccessConditionHeader() does only seem to accept array|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

459
        $this->addOptionalAccessConditionHeader($headers, /** @scrutinizer ignore-type */ $accessCondition);
Loading history...
460
461
        if (!is_null($options)) {
462
            $options = new BlobServiceOptions();
463
        }
464
        
465
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
466
467
        return $this->sendAsync(
468
            $method,
469
            $headers,
470
            $queryParams,
471
            $postParams,
472
            $path,
473
            $expectedStatusCode,
0 ignored issues
show
Bug introduced by
$expectedStatusCode of type string is incompatible with the type array|integer expected by parameter $expected of MicrosoftAzure\Storage\C...eRestProxy::sendAsync(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

473
            /** @scrutinizer ignore-type */ $expectedStatusCode,
Loading history...
474
            Resources::EMPTY_STRING,
475
            $options
476
        );
477
    }
478
479
    /**
480
     * Creates promise that does actual work for create and clear blob pages.
481
     *
482
     * @param string                 $action    Either clear or create.
483
     * @param string                 $container The container name.
484
     * @param string                 $blob      The blob name.
485
     * @param Range          $range     The page ranges.
486
     * @param string                 $content   The content string.
487
     * @param CreateBlobPagesOptions $options   The optional parameters.
488
     *
489
     * @return \GuzzleHttp\Promise\PromiseInterface
490
     */
491
    private function _updatePageBlobPagesAsyncImpl(
492
        $action,
493
        $container,
494
        $blob,
495
        Range $range,
496
        $content,
497
        CreateBlobPagesOptions $options = null
498
    ) {
499
        Validate::isString($blob, 'blob');
500
        Validate::notNullOrEmpty($blob, 'blob');
501
        Validate::isString($container, 'container');
502
        Validate::isString($content, 'content');
503
        Validate::isTrue(
504
            $range instanceof Range,
505
            sprintf(
506
                Resources::INVALID_PARAM_MSG,
507
                'range',
508
                get_class(new Range(0))
509
            )
510
        );
511
        $body = Psr7\stream_for($content);
0 ignored issues
show
Bug introduced by
The function stream_for was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

511
        $body = /** @scrutinizer ignore-call */ Psr7\stream_for($content);
Loading history...
512
        
513
        $method      = Resources::HTTP_PUT;
514
        $headers     = array();
515
        $queryParams = array();
516
        $postParams  = array();
517
        $path        = $this->_createPath($container, $blob);
518
        
519
        if (is_null($options)) {
520
            $options = new CreateBlobPagesOptions();
521
        }
522
        
523
        $headers = $this->_addOptionalRangeHeader(
524
            $headers,
525
            $range->getStart(),
526
            $range->getEnd()
527
        );
528
        
529
        $headers = $this->addOptionalAccessConditionHeader(
530
            $headers,
531
            $options->getAccessConditions()
532
        );
533
        
534
        $this->addOptionalHeader(
535
            $headers,
536
            Resources::X_MS_LEASE_ID,
537
            $options->getLeaseId()
538
        );
539
        $this->addOptionalHeader(
540
            $headers,
541
            Resources::CONTENT_MD5,
542
            $options->getContentMD5()
543
        );
544
        $this->addOptionalHeader(
545
            $headers,
546
            Resources::X_MS_PAGE_WRITE,
547
            $action
548
        );
549
        $this->addOptionalHeader(
550
            $headers,
551
            Resources::CONTENT_TYPE,
552
            Resources::URL_ENCODED_CONTENT_TYPE
553
        );
554
        $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'page');
555
        
556
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
557
558
        return $this->sendAsync(
559
            $method,
560
            $headers,
561
            $queryParams,
562
            $postParams,
563
            $path,
564
            Resources::STATUS_CREATED,
565
            $body,
566
            $options
567
        )->then(function ($response) {
568
            return CreateBlobPagesResult::create(
569
                HttpFormatter::formatHeaders($response->getHeaders())
570
            );
571
        }, null);
572
    }
573
    
574
    /**
575
     * Lists all of the containers in the given storage account.
576
     *
577
     * @param ListContainersOptions $options The optional parameters.
578
     *
579
     * @return ListContainersResult
580
     *
581
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179352.aspx
582
     */
583
    public function listContainers(ListContainersOptions $options = null)
584
    {
585
        return $this->listContainersAsync($options)->wait();
586
    }
587
588
    /**
589
     * Create a promise for lists all of the containers in the given
590
     * storage account.
591
     *
592
     * @param  ListContainersOptions $options The optional parameters.
593
     *
594
     * @return \GuzzleHttp\Promise\PromiseInterface
595
     */
596
    public function listContainersAsync(
597
        ListContainersOptions $options = null
598
    ) {
599
        $method      = Resources::HTTP_GET;
600
        $headers     = array();
601
        $queryParams = array();
602
        $postParams  = array();
603
        $path        = Resources::EMPTY_STRING;
604
        
605
        if (is_null($options)) {
606
            $options = new ListContainersOptions();
607
        }
608
        
609
        $this->addOptionalQueryParam(
610
            $queryParams,
611
            Resources::QP_COMP,
612
            'list'
613
        );
614
        $this->addOptionalQueryParam(
615
            $queryParams,
616
            Resources::QP_PREFIX,
617
            $options->getPrefix()
618
        );
619
        $this->addOptionalQueryParam(
620
            $queryParams,
621
            Resources::QP_MARKER,
622
            $options->getNextMarker()
623
        );
624
        $this->addOptionalQueryParam(
625
            $queryParams,
626
            Resources::QP_MAX_RESULTS,
627
            $options->getMaxResults()
628
        );
629
        $isInclude = $options->getIncludeMetadata();
630
        $isInclude = $isInclude ? 'metadata' : null;
631
        $this->addOptionalQueryParam(
632
            $queryParams,
633
            Resources::QP_INCLUDE,
634
            $isInclude
635
        );
636
637
        $dataSerializer = $this->dataSerializer;
638
639
        return $this->sendAsync(
640
            $method,
641
            $headers,
642
            $queryParams,
643
            $postParams,
644
            $path,
645
            Resources::STATUS_OK,
646
            Resources::EMPTY_STRING,
647
            $options
648
        )->then(function ($response) use ($dataSerializer) {
0 ignored issues
show
Unused Code introduced by
The import $dataSerializer is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
649
            $parsed = $this->dataSerializer->unserialize($response->getBody());
650
            return ListContainersResult::create(
651
                $parsed,
652
                Utilities::getLocationFromHeaders($response->getHeaders())
653
            );
654
        });
655
    }
656
    
657
    /**
658
     * Creates a new container in the given storage account.
659
     *
660
     * @param string                        $container The container name.
661
     * @param Models\CreateContainerOptions $options   The optional parameters.
662
     *
663
     * @return void
664
     *
665
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179468.aspx
666
     */
667
    public function createContainer(
668
        $container,
669
        Models\CreateContainerOptions $options = null
670
    ) {
671
        $this->createContainerAsync($container, $options)->wait();
672
    }
673
674
    /**
675
     * Creates a new container in the given storage account.
676
     *
677
     * @param string                        $container The container name.
678
     * @param Models\CreateContainerOptions $options   The optional parameters.
679
     *
680
     * @return \GuzzleHttp\Promise\PromiseInterface
681
     *
682
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179468.aspx
683
     */
684
    public function createContainerAsync(
685
        $container,
686
        Models\CreateContainerOptions $options = null
687
    ) {
688
        Validate::isString($container, 'container');
689
        Validate::notNullOrEmpty($container, 'container');
690
        
691
        $method      = Resources::HTTP_PUT;
692
        $headers     = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $headers is dead and can be removed.
Loading history...
693
        $postParams  = array();
694
        $queryParams = array(Resources::QP_REST_TYPE => 'container');
695
        $path        = $this->_createPath($container);
696
        
697
        if (is_null($options)) {
698
            $options = new CreateContainerOptions();
699
        }
700
701
        $metadata = $options->getMetadata();
702
        $headers  = $this->generateMetadataHeaders($metadata);
703
        $this->addOptionalHeader(
704
            $headers,
705
            Resources::X_MS_BLOB_PUBLIC_ACCESS,
706
            $options->getPublicAccess()
707
        );
708
709
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
710
        
711
        return $this->sendAsync(
712
            $method,
713
            $headers,
714
            $queryParams,
715
            $postParams,
716
            $path,
717
            Resources::STATUS_CREATED,
718
            Resources::EMPTY_STRING,
719
            $options
720
        );
721
    }
722
    
723
    /**
724
     * Deletes a container in the given storage account.
725
     *
726
     * @param string                        $container The container name.
727
     * @param Models\BlobServiceOptions     $options   The optional parameters.
728
     *
729
     * @return void
730
     *
731
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179408.aspx
732
     */
733
    public function deleteContainer(
734
        $container,
735
        Models\BlobServiceOptions $options = null
736
    ) {
737
        $this->deleteContainerAsync($container, $options)->wait();
738
    }
739
740
    /**
741
     * Create a promise for deleting a container.
742
     *
743
     * @param  string                             $container name of the container
744
     * @param  Models\BlobServiceOptions|null     $options   optional parameters
745
     *
746
     * @return \GuzzleHttp\Promise\PromiseInterface
747
     */
748
    public function deleteContainerAsync(
749
        $container,
750
        Models\BlobServiceOptions $options = null
751
    ) {
752
        Validate::isString($container, 'container');
753
        Validate::notNullOrEmpty($container, 'container');
754
        
755
        $method      = Resources::HTTP_DELETE;
756
        $headers     = array();
757
        $postParams  = array();
758
        $queryParams = array();
759
        $path        = $this->_createPath($container);
760
        
761
        if (is_null($options)) {
762
            $options = new BlobServiceOptions();
763
        }
764
        
765
        $this->addOptionalHeader(
766
            $headers,
767
            Resources::X_MS_LEASE_ID,
768
            $options->getLeaseId()
769
        );
770
        $headers = $this->addOptionalAccessConditionHeader(
771
            $headers,
772
            $options->getAccessConditions()
773
        );
774
        
775
        $this->addOptionalQueryParam(
776
            $queryParams,
777
            Resources::QP_REST_TYPE,
778
            'container'
779
        );
780
781
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
782
783
        return $this->sendAsync(
784
            $method,
785
            $headers,
786
            $queryParams,
787
            $postParams,
788
            $path,
789
            Resources::STATUS_ACCEPTED,
790
            Resources::EMPTY_STRING,
791
            $options
792
        );
793
    }
794
    
795
    /**
796
     * Returns all properties and metadata on the container.
797
     *
798
     * @param string                    $container name
799
     * @param Models\BlobServiceOptions $options   optional parameters
800
     *
801
     * @return Models\GetContainerPropertiesResult
802
     *
803
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179370.aspx
804
     */
805
    public function getContainerProperties(
806
        $container,
807
        Models\BlobServiceOptions $options = null
808
    ) {
809
        return $this->getContainerPropertiesAsync($container, $options)->wait();
810
    }
811
812
    /**
813
     * Create promise to return all properties and metadata on the container.
814
     *
815
     * @param string                    $container name
816
     * @param Models\BlobServiceOptions $options   optional parameters
817
     *
818
     * @return \GuzzleHttp\Promise\PromiseInterface
819
     *
820
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179370.aspx
821
     */
822
    public function getContainerPropertiesAsync(
823
        $container,
824
        Models\BlobServiceOptions $options = null
825
    ) {
826
        return $this->_getContainerPropertiesAsyncImpl($container, $options);
827
    }
828
    
829
    /**
830
     * Returns only user-defined metadata for the specified container.
831
     *
832
     * @param string                    $container name
833
     * @param Models\BlobServiceOptions $options   optional parameters
834
     *
835
     * @return Models\GetContainerPropertiesResult
836
     *
837
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691976.aspx
838
     */
839
    public function getContainerMetadata(
840
        $container,
841
        Models\BlobServiceOptions $options = null
842
    ) {
843
        return $this->getContainerMetadataAsync($container, $options)->wait();
844
    }
845
846
    /**
847
     * Create promise to return only user-defined metadata for the specified
848
     * container.
849
     *
850
     * @param string                    $container name
851
     * @param Models\BlobServiceOptions $options   optional parameters
852
     *
853
     * @return \GuzzleHttp\Promise\PromiseInterface
854
     *
855
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691976.aspx
856
     */
857
    public function getContainerMetadataAsync(
858
        $container,
859
        Models\BlobServiceOptions $options = null
860
    ) {
861
        return $this->_getContainerPropertiesAsyncImpl($container, $options, 'metadata');
862
    }
863
    
864
    /**
865
     * Gets the access control list (ACL) and any container-level access policies
866
     * for the container.
867
     *
868
     * @param string                    $container The container name.
869
     * @param Models\BlobServiceOptions $options   The optional parameters.
870
     *
871
     * @return Models\GetContainerACLResult
872
     *
873
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179469.aspx
874
     */
875
    public function getContainerAcl(
876
        $container,
877
        Models\BlobServiceOptions $options = null
878
    ) {
879
        return $this->getContainerAclAsync($container, $options)->wait();
880
    }
881
882
    /**
883
     * Creates the promise to get the access control list (ACL) and any
884
     * container-level access policies for the container.
885
     *
886
     * @param string                    $container The container name.
887
     * @param Models\BlobServiceOptions $options   The optional parameters.
888
     *
889
     * @return \GuzzleHttp\Promise\PromiseInterface
890
     *
891
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179469.aspx
892
     */
893
    public function getContainerAclAsync(
894
        $container,
895
        Models\BlobServiceOptions $options = null
896
    ) {
897
        Validate::isString($container, 'container');
898
        
899
        $method      = Resources::HTTP_GET;
900
        $headers     = array();
901
        $postParams  = array();
902
        $queryParams = array();
903
        $path        = $this->_createPath($container);
904
        $statusCode  = Resources::STATUS_OK;
0 ignored issues
show
Unused Code introduced by
The assignment to $statusCode is dead and can be removed.
Loading history...
905
        
906
        if (is_null($options)) {
907
            $options = new BlobServiceOptions();
908
        }
909
        
910
        $this->addOptionalQueryParam(
911
            $queryParams,
912
            Resources::QP_REST_TYPE,
913
            'container'
914
        );
915
        $this->addOptionalQueryParam(
916
            $queryParams,
917
            Resources::QP_COMP,
918
            'acl'
919
        );
920
921
        $this->addOptionalHeader(
922
            $headers,
923
            Resources::X_MS_LEASE_ID,
924
            $options->getLeaseId()
925
        );
926
        $this->addOptionalAccessConditionHeader(
927
            $headers,
928
            $options->getAccessConditions()
929
        );
930
931
        $dataSerializer = $this->dataSerializer;
932
        
933
        $promise = $this->sendAsync(
934
            $method,
935
            $headers,
936
            $queryParams,
937
            $postParams,
938
            $path,
939
            Resources::STATUS_OK,
940
            Resources::EMPTY_STRING,
941
            $options
942
        );
943
944
        return $promise->then(function ($response) use ($dataSerializer) {
945
            $responseHeaders = HttpFormatter::formatHeaders($response->getHeaders());
946
            
947
            $access = Utilities::tryGetValue(
948
                $responseHeaders,
949
                Resources::X_MS_BLOB_PUBLIC_ACCESS
950
            );
951
            $etag = Utilities::tryGetValue($responseHeaders, Resources::ETAG);
952
            $modified = Utilities::tryGetValue(
953
                $responseHeaders,
954
                Resources::LAST_MODIFIED
955
            );
956
            $modifiedDate = Utilities::convertToDateTime($modified);
957
            $parsed       = $dataSerializer->unserialize($response->getBody());
958
            
959
            return GetContainerAclResult::create(
960
                $access,
961
                $etag,
962
                $modifiedDate,
963
                $parsed
964
            );
965
        }, null);
966
    }
967
    
968
    /**
969
     * Sets the ACL and any container-level access policies for the container.
970
     *
971
     * @param string                    $container name
972
     * @param Models\ContainerACL       $acl       access control list for container
973
     * @param Models\BlobServiceOptions $options   optional parameters
974
     *
975
     * @return void
976
     *
977
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179391.aspx
978
     */
979
    public function setContainerAcl(
980
        $container,
981
        Models\ContainerACL $acl,
982
        Models\BlobServiceOptions $options = null
983
    ) {
984
        $this->setContainerAclAsync($container, $acl, $options)->wait();
985
    }
986
987
    /**
988
     * Creates promise to set the ACL and any container-level access policies
989
     * for the container.
990
     *
991
     * @param string                    $container name
992
     * @param Models\ContainerACL       $acl       access control list for container
993
     * @param Models\BlobServiceOptions $options   optional parameters
994
     *
995
     * @return \GuzzleHttp\Promise\PromiseInterface
996
     *
997
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179391.aspx
998
     */
999
    public function setContainerAclAsync(
1000
        $container,
1001
        Models\ContainerACL $acl,
1002
        Models\BlobServiceOptions $options = null
1003
    ) {
1004
        Validate::isString($container, 'container');
1005
        Validate::notNullOrEmpty($acl, 'acl');
1006
        
1007
        $method      = Resources::HTTP_PUT;
1008
        $headers     = array();
1009
        $postParams  = array();
1010
        $queryParams = array();
1011
        $path        = $this->_createPath($container);
1012
        $body        = $acl->toXml($this->dataSerializer);
1013
        
1014
        if (is_null($options)) {
1015
            $options = new BlobServiceOptions();
1016
        }
1017
        
1018
        $this->addOptionalQueryParam(
1019
            $queryParams,
1020
            Resources::QP_REST_TYPE,
1021
            'container'
1022
        );
1023
        $this->addOptionalQueryParam(
1024
            $queryParams,
1025
            Resources::QP_COMP,
1026
            'acl'
1027
        );
1028
        $this->addOptionalHeader(
1029
            $headers,
1030
            Resources::X_MS_BLOB_PUBLIC_ACCESS,
1031
            $acl->getPublicAccess()
1032
        );
1033
        $this->addOptionalHeader(
1034
            $headers,
1035
            Resources::CONTENT_TYPE,
1036
            Resources::URL_ENCODED_CONTENT_TYPE
1037
        );
1038
        $this->addOptionalHeader(
1039
            $headers,
1040
            Resources::X_MS_LEASE_ID,
1041
            $options->getLeaseId()
1042
        );
1043
        $this->addOptionalAccessConditionHeader(
1044
            $headers,
1045
            $options->getAccessConditions()
1046
        );
1047
1048
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
1049
1050
        return $this->sendAsync(
1051
            $method,
1052
            $headers,
1053
            $queryParams,
1054
            $postParams,
1055
            $path,
1056
            Resources::STATUS_OK,
1057
            $body,
1058
            $options
1059
        );
1060
    }
1061
    
1062
    /**
1063
     * Sets metadata headers on the container.
1064
     *
1065
     * @param string                    $container name
1066
     * @param array                     $metadata  metadata key/value pair.
1067
     * @param Models\BlobServiceOptions $options   optional parameters
1068
     *
1069
     * @return void
1070
     *
1071
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179362.aspx
1072
     */
1073
    public function setContainerMetadata(
1074
        $container,
1075
        array $metadata,
1076
        Models\BlobServiceOptions $options = null
1077
    ) {
1078
        $this->setContainerMetadataAsync($container, $metadata, $options)->wait();
1079
    }
1080
1081
    /**
1082
     * Sets metadata headers on the container.
1083
     *
1084
     * @param string                   $container name
1085
     * @param array                    $metadata  metadata key/value pair.
1086
     * @param Models\BlobServiceOptions $options   optional parameters
1087
     *
1088
     * @return \GuzzleHttp\Promise\PromiseInterface
1089
     *
1090
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179362.aspx
1091
     */
1092
    public function setContainerMetadataAsync(
1093
        $container,
1094
        array $metadata,
1095
        Models\BlobServiceOptions $options = null
1096
    ) {
1097
        Validate::isString($container, 'container');
1098
        Utilities::validateMetadata($metadata);
1099
        
1100
        $method      = Resources::HTTP_PUT;
1101
        $headers     = $this->generateMetadataHeaders($metadata);
1102
        $postParams  = array();
1103
        $queryParams = array();
1104
        $path        = $this->_createPath($container);
1105
        
1106
        if (is_null($options)) {
1107
            $options = new BlobServiceOptions();
1108
        }
1109
        
1110
        $this->addOptionalQueryParam(
1111
            $queryParams,
1112
            Resources::QP_REST_TYPE,
1113
            'container'
1114
        );
1115
        $this->addOptionalQueryParam(
1116
            $queryParams,
1117
            Resources::QP_COMP,
1118
            'metadata'
1119
        );
1120
1121
        $this->addOptionalHeader(
1122
            $headers,
1123
            Resources::X_MS_LEASE_ID,
1124
            $options->getLeaseId()
1125
        );
1126
        
1127
        $headers = $this->addOptionalAccessConditionHeader(
1128
            $headers,
1129
            $options->getAccessConditions()
1130
        );
1131
1132
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
1133
1134
        return $this->sendAsync(
1135
            $method,
1136
            $headers,
1137
            $queryParams,
1138
            $postParams,
1139
            $path,
1140
            Resources::STATUS_OK,
1141
            Resources::EMPTY_STRING,
1142
            $options
1143
        );
1144
    }
1145
    
1146
    /**
1147
     * Lists all of the blobs in the given container.
1148
     *
1149
     * @param string                  $container The container name.
1150
     * @param Models\ListBlobsOptions $options   The optional parameters.
1151
     *
1152
     * @return Models\ListBlobsResult
1153
     *
1154
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx
1155
     */
1156
    public function listBlobs($container, Models\ListBlobsOptions $options = null)
1157
    {
1158
        return $this->listBlobsAsync($container, $options)->wait();
1159
    }
1160
1161
    /**
1162
     * Creates promise to list all of the blobs in the given container.
1163
     *
1164
     * @param string                  $container The container name.
1165
     * @param Models\ListBlobsOptions $options   The optional parameters.
1166
     *
1167
     * @return \GuzzleHttp\Promise\PromiseInterface
1168
     *
1169
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx
1170
     */
1171
    public function listBlobsAsync(
1172
        $container,
1173
        Models\ListBlobsOptions $options = null
1174
    ) {
1175
        Validate::isString($container, 'container');
1176
        
1177
        $method      = Resources::HTTP_GET;
1178
        $headers     = array();
1179
        $postParams  = array();
1180
        $queryParams = array();
1181
        $path        = $this->_createPath($container);
1182
        
1183
        if (is_null($options)) {
1184
            $options = new ListBlobsOptions();
1185
        }
1186
        
1187
        $this->addOptionalQueryParam(
1188
            $queryParams,
1189
            Resources::QP_REST_TYPE,
1190
            'container'
1191
        );
1192
        $this->addOptionalQueryParam(
1193
            $queryParams,
1194
            Resources::QP_COMP,
1195
            'list'
1196
        );
1197
        $this->addOptionalQueryParam(
1198
            $queryParams,
1199
            Resources::QP_PREFIX,
1200
            str_replace('\\', '/', $options->getPrefix())
1201
        );
1202
        $this->addOptionalQueryParam(
1203
            $queryParams,
1204
            Resources::QP_MARKER,
1205
            $options->getNextMarker()
1206
        );
1207
        $this->addOptionalQueryParam(
1208
            $queryParams,
1209
            Resources::QP_DELIMITER,
1210
            $options->getDelimiter()
1211
        );
1212
        $this->addOptionalQueryParam(
1213
            $queryParams,
1214
            Resources::QP_MAX_RESULTS,
1215
            $options->getMaxResults()
1216
        );
1217
        
1218
        $includeMetadata         = $options->getIncludeMetadata();
1219
        $includeSnapshots        = $options->getIncludeSnapshots();
1220
        $includeUncommittedBlobs = $options->getIncludeUncommittedBlobs();
1221
        $includecopy             = $options->getIncludeCopy();
1222
        
1223
        $includeValue = static::groupQueryValues(
1224
            array(
1225
                $includeMetadata ? 'metadata' : null,
1226
                $includeSnapshots ? 'snapshots' : null,
1227
                $includeUncommittedBlobs ? 'uncommittedblobs' : null,
1228
                $includecopy ? 'copy' : null
1229
            )
1230
        );
1231
        
1232
        $this->addOptionalQueryParam(
1233
            $queryParams,
1234
            Resources::QP_INCLUDE,
1235
            $includeValue
1236
        );
1237
1238
        $dataSerializer = $this->dataSerializer;
1239
1240
        return $this->sendAsync(
1241
            $method,
1242
            $headers,
1243
            $queryParams,
1244
            $postParams,
1245
            $path,
1246
            Resources::STATUS_OK,
1247
            Resources::EMPTY_STRING,
1248
            $options
1249
        )->then(function ($response) use ($dataSerializer) {
1250
            $parsed = $dataSerializer->unserialize($response->getBody());
1251
            return ListBlobsResult::create(
1252
                $parsed,
1253
                Utilities::getLocationFromHeaders($response->getHeaders())
1254
            );
1255
        }, null);
1256
    }
1257
    
1258
    /**
1259
     * Creates a new page blob. Note that calling createPageBlob to create a page
1260
     * blob only initializes the blob.
1261
     * To add content to a page blob, call createBlobPages method.
1262
     *
1263
     * @param string                   $container The container name.
1264
     * @param string                   $blob      The blob name.
1265
     * @param integer                  $length    Specifies the maximum size
1266
     *                                            for the page blob, up to 1 TB.
1267
     *                                            The page blob size must be
1268
     *                                            aligned to a 512-byte
1269
     *                                            boundary.
1270
     * @param Models\CreateBlobOptions $options   The optional parameters.
1271
     *
1272
     * @return Models\PutBlobResult
1273
     *
1274
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1275
     */
1276
    public function createPageBlob(
1277
        $container,
1278
        $blob,
1279
        $length,
1280
        Models\CreateBlobOptions $options = null
1281
    ) {
1282
        return $this->createPageBlobAsync(
1283
            $container,
1284
            $blob,
1285
            $length,
1286
            $options
1287
        )->wait();
1288
    }
1289
1290
    /**
1291
     * Creates promise to create a new page blob. Note that calling
1292
     * createPageBlob to create a page blob only initializes the blob.
1293
     * To add content to a page blob, call createBlobPages method.
1294
     *
1295
     * @param string                   $container The container name.
1296
     * @param string                   $blob      The blob name.
1297
     * @param integer                  $length    Specifies the maximum size
1298
     *                                            for the page blob, up to 1 TB.
1299
     *                                            The page blob size must be
1300
     *                                            aligned to a 512-byte
1301
     *                                            boundary.
1302
     * @param Models\CreateBlobOptions $options   The optional parameters.
1303
     *
1304
     * @return \GuzzleHttp\Promise\PromiseInterface
1305
     *
1306
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1307
     */
1308
    public function createPageBlobAsync(
1309
        $container,
1310
        $blob,
1311
        $length,
1312
        Models\CreateBlobOptions $options = null
1313
    ) {
1314
        Validate::isString($container, 'container');
1315
        Validate::isString($blob, 'blob');
1316
        Validate::notNullOrEmpty($blob, 'blob');
1317
        Validate::isInteger($length, 'length');
1318
        Validate::notNull($length, 'length');
1319
        
1320
        $method      = Resources::HTTP_PUT;
1321
        $headers     = array();
1322
        $postParams  = array();
1323
        $queryParams = array();
1324
        $path        = $this->_createPath($container, $blob);
1325
        $statusCode  = Resources::STATUS_CREATED;
0 ignored issues
show
Unused Code introduced by
The assignment to $statusCode is dead and can be removed.
Loading history...
1326
        
1327
        if (is_null($options)) {
1328
            $options = new CreateBlobOptions();
1329
        }
1330
        
1331
        $this->addOptionalHeader(
1332
            $headers,
1333
            Resources::X_MS_BLOB_TYPE,
1334
            BlobType::PAGE_BLOB
1335
        );
1336
        $this->addOptionalHeader(
1337
            $headers,
1338
            Resources::X_MS_BLOB_CONTENT_LENGTH,
1339
            $length
1340
        );
1341
        $this->addOptionalHeader(
1342
            $headers,
1343
            Resources::X_MS_BLOB_SEQUENCE_NUMBER,
1344
            $options->getSequenceNumber()
1345
        );
1346
        $headers = $this->_addCreateBlobOptionalHeaders($options, $headers);
1347
        
1348
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
1349
1350
        return $this->sendAsync(
1351
            $method,
1352
            $headers,
1353
            $queryParams,
1354
            $postParams,
1355
            $path,
1356
            Resources::STATUS_CREATED,
1357
            Resources::EMPTY_STRING,
1358
            $options
1359
        )->then(function ($response) {
1360
            return PutBlobResult::create(
1361
                HttpFormatter::formatHeaders($response->getHeaders())
1362
            );
1363
        }, null);
1364
    }
1365
    
1366
    /**
1367
     * Create a new append blob.
1368
     * If the blob already exists on the service, it will be overwritten.
1369
     *
1370
     * @param string                   $container The container name.
1371
     * @param string                   $blob      The blob name.
1372
     * @param Models\CreateBlobOptions $options   The optional parameters.
1373
     *
1374
     * @return Models\PutBlobResult
1375
     *
1376
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1377
     */
1378
    public function createAppendBlob(
1379
        $container,
1380
        $blob,
1381
        Models\CreateBlobOptions $options = null
1382
    ) {
1383
        return $this->createAppendBlobAsync(
1384
            $container,
1385
            $blob,
1386
            $options
1387
        )->wait();
1388
    }
1389
1390
    /**
1391
     * Creates promise to create a new append blob.
1392
     * If the blob already exists on the service, it will be overwritten.
1393
     *
1394
     * @param string                   $container The container name.
1395
     * @param string                   $blob      The blob name.
1396
     * @param Models\CreateBlobOptions $options   The optional parameters.
1397
     *
1398
     * @return \GuzzleHttp\Promise\PromiseInterface
1399
     *
1400
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1401
     */
1402
    public function createAppendBlobAsync(
1403
        $container,
1404
        $blob,
1405
        Models\CreateBlobOptions $options = null
1406
    ) {
1407
        Validate::isString($container, 'container');
1408
        Validate::notNullOrEmpty($container, 'container');
1409
        Validate::isString($blob, 'blob');
1410
        Validate::notNullOrEmpty($blob, 'blob');
1411
1412
        $method      = Resources::HTTP_PUT;
1413
        $headers     = array();
1414
        $postParams  = array();
1415
        $queryParams = array();
1416
        $path        = $this->_createPath($container, $blob);
1417
        $statusCode  = Resources::STATUS_CREATED;
0 ignored issues
show
Unused Code introduced by
The assignment to $statusCode is dead and can be removed.
Loading history...
1418
1419
        if (is_null($options)) {
1420
            $options = new CreateBlobOptions();
1421
        }
1422
        
1423
        $this->addOptionalHeader(
1424
            $headers,
1425
            Resources::X_MS_BLOB_TYPE,
1426
            BlobType::APPEND_BLOB
1427
        );
1428
        $headers = $this->_addCreateBlobOptionalHeaders($options, $headers);
1429
1430
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
1431
1432
        return $this->sendAsync(
1433
            $method,
1434
            $headers,
1435
            $queryParams,
1436
            $postParams,
1437
            $path,
1438
            Resources::STATUS_CREATED,
1439
            Resources::EMPTY_STRING,
1440
            $options
1441
        )->then(function ($response) {
1442
            return PutBlobResult::create(
1443
                HttpFormatter::formatHeaders($response->getHeaders())
1444
            );
1445
        }, null);
1446
    }
1447
    
1448
    /**
1449
     * Creates a new block blob or updates the content of an existing block blob.
1450
     *
1451
     * Updating an existing block blob overwrites any existing metadata on the blob.
1452
     * Partial updates are not supported with createBlockBlob the content of the
1453
     * existing blob is overwritten with the content of the new blob. To perform a
1454
     * partial update of the content of a block blob, use the createBlockList
1455
     * method.
1456
     * Note that the default content type is application/octet-stream.
1457
     *
1458
     * @param string                          $container The name of the container.
1459
     * @param string                          $blob      The name of the blob.
1460
     * @param string|resource|StreamInterface $content   The content of the blob.
1461
     * @param Models\CreateBlobOptions        $options   The optional parameters.
1462
     *
1463
     * @return Models\PutBlobResult
1464
     *
1465
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1466
     */
1467
    public function createBlockBlob(
1468
        $container,
1469
        $blob,
1470
        $content,
1471
        Models\CreateBlobOptions $options = null
1472
    ) {
1473
        return $this->createBlockBlobAsync(
1474
            $container,
1475
            $blob,
1476
            $content,
1477
            $options
1478
        )->wait();
0 ignored issues
show
Bug introduced by
The method wait() does not exist on MicrosoftAzure\Storage\Blob\Models\PutBlobResult. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1478
        )->/** @scrutinizer ignore-call */ wait();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1479
    }
1480
1481
    /**
1482
     * Creates a promise to create a new block blob or updates the content of
1483
     * an existing block blob.
1484
     *
1485
     * Updating an existing block blob overwrites any existing metadata on the blob.
1486
     * Partial updates are not supported with createBlockBlob the content of the
1487
     * existing blob is overwritten with the content of the new blob. To perform a
1488
     * partial update of the content of a block blob, use the createBlockList
1489
     * method.
1490
     *
1491
     * @param string                          $container The name of the container.
1492
     * @param string                          $blob      The name of the blob.
1493
     * @param string|resource|StreamInterface $content   The content of the blob.
1494
     * @param Models\CreateBlobOptions        $options   The optional parameters.
1495
     *
1496
     * @return Models\PutBlobResult
1497
     *
1498
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1499
     */
1500
    public function createBlockBlobAsync(
1501
        $container,
1502
        $blob,
1503
        $content,
1504
        Models\CreateBlobOptions $options = null
1505
    ) {
1506
        $body = Psr7\stream_for($content);
0 ignored issues
show
Bug introduced by
The function stream_for was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1506
        $body = /** @scrutinizer ignore-call */ Psr7\stream_for($content);
Loading history...
1507
1508
        //If the size of the stream is not seekable or larger than the single
1509
        //upload threashold then call concurrent upload. Otherwise call putBlob.
1510
        $promise = null;
1511
        if (!Utilities::isStreamLargerThanSizeOrNotSeekable(
1512
            $body,
1513
            $this->_SingleBlobUploadThresholdInBytes
1514
        )) {
1515
            $promise = $this->createBlockBlobBySingleUploadAsync(
1516
                $container,
1517
                $blob,
1518
                $body,
1519
                $options
1520
            );
1521
        } else {
1522
            // This is for large or failsafe upload
1523
            $promise = $this->createBlockBlobByMultipleUploadAsync(
1524
                $container,
1525
                $blob,
1526
                $body,
1527
                $options
1528
            );
1529
        }
1530
1531
        //return the parsed result, instead of the raw response.
1532
        return $promise;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $promise returns the type GuzzleHttp\Promise\PromiseInterface which is incompatible with the documented return type MicrosoftAzure\Storage\Blob\Models\PutBlobResult.
Loading history...
1533
    }
1534
1535
    /**
1536
     * Create a new page blob and upload the content to the page blob.
1537
     *
1538
     * @param string                          $container The name of the container.
1539
     * @param string                          $blob      The name of the blob.
1540
     * @param int                             $length    The length of the blob.
1541
     * @param string|resource|StreamInterface $content   The content of the blob.
1542
     * @param Models\CreateBlobOptions        $options   The optional parameters.
1543
     *
1544
     * @return Models\GetBlobPropertiesResult
1545
     *
1546
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-blob-properties
1547
     */
1548
    public function createPageBlobFromContent(
1549
        $container,
1550
        $blob,
1551
        $length,
1552
        $content,
1553
        Models\CreateBlobOptions $options = null
1554
    ) {
1555
        return $this->createPageBlobFromContentAsync(
1556
            $container,
1557
            $blob,
1558
            $length,
1559
            $content,
1560
            $options
1561
        )->wait();
1562
    }
1563
1564
    /**
1565
     * Creates a promise to create a new page blob and upload the content
1566
     * to the page blob.
1567
     *
1568
     * @param string                          $container The name of the container.
1569
     * @param string                          $blob      The name of the blob.
1570
     * @param int                             $length    The length of the blob.
1571
     * @param string|resource|StreamInterface $content   The content of the blob.
1572
     * @param Models\CreateBlobOptions        $options   The optional parameters.
1573
     *
1574
     * @return \GuzzleHttp\Promise\PromiseInterface
1575
     *
1576
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-blob-properties
1577
     */
1578
    public function createPageBlobFromContentAsync(
1579
        $container,
1580
        $blob,
1581
        $length,
1582
        $content,
1583
        Models\CreateBlobOptions $options = null
1584
    ) {
1585
        $body = Psr7\stream_for($content);
0 ignored issues
show
Bug introduced by
The function stream_for was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1585
        $body = /** @scrutinizer ignore-call */ Psr7\stream_for($content);
Loading history...
1586
        $self = $this;
1587
1588
        $createBlobPromise = $this->createPageBlobAsync(
1589
            $container,
1590
            $blob,
1591
            $length,
1592
            $options
1593
        );
1594
1595
        $uploadBlobPromise = $createBlobPromise->then(
1596
            function ($value) use (
1597
                $self,
1598
                $container,
1599
                $blob,
1600
                $body,
1601
                $options
1602
            ) {
1603
                $result = $value;
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
1604
                return $self->uploadPageBlobAsync(
1605
                    $container,
1606
                    $blob,
1607
                    $body,
1608
                    $options
1609
                );
1610
            },
1611
            null
1612
        );
1613
1614
        return $uploadBlobPromise->then(
1615
            function ($value) use (
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1615
            function (/** @scrutinizer ignore-unused */ $value) use (

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1616
                $self,
1617
                $container,
1618
                $blob,
1619
                $options
1620
            ) {
1621
                $getBlobPropertiesOptions = new GetBlobPropertiesOptions();
1622
                $getBlobPropertiesOptions->setLeaseId($options->getLeaseId());
1623
1624
                return $self->getBlobPropertiesAsync(
1625
                    $container,
1626
                    $blob,
1627
                    $getBlobPropertiesOptions
1628
                );
1629
            },
1630
            null
1631
        );
1632
    }
1633
1634
    /**
1635
     * Creates promise to create a new block blob or updates the content of an
1636
     * existing block blob. This only supports contents smaller than single
1637
     * upload threashold.
1638
     *
1639
     * Updating an existing block blob overwrites any existing metadata on
1640
     * the blob.
1641
     *
1642
     * @param string                   $container The name of the container.
1643
     * @param string                   $blob      The name of the blob.
1644
     * @param StreamInterface          $content   The content of the blob.
1645
     * @param Models\CreateBlobOptions $options   The optional parameters.
1646
     *
1647
     * @return \GuzzleHttp\Promise\PromiseInterface
1648
     *
1649
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1650
     */
1651
    protected function createBlockBlobBySingleUploadAsync(
1652
        $container,
1653
        $blob,
1654
        $content,
1655
        Models\CreateBlobOptions $options = null
1656
    ) {
1657
        Validate::isString($container, 'container');
1658
        Validate::isString($blob, 'blob');
1659
        Validate::notNullOrEmpty($blob, 'blob');
1660
        Validate::isTrue(
1661
            $options == null ||
1662
            $options instanceof CreateBlobOptions,
1663
            sprintf(
1664
                Resources::INVALID_PARAM_MSG,
1665
                'options',
1666
                get_class(new CreateBlobOptions())
1667
            )
1668
        );
1669
        
1670
        $method      = Resources::HTTP_PUT;
1671
        $headers     = array();
1672
        $postParams  = array();
1673
        $queryParams = array();
1674
        $path        = $this->_createPath($container, $blob);
1675
1676
        if (is_null($options)) {
1677
            $options = new CreateBlobOptions();
1678
        }
1679
        
1680
        
1681
        $headers = $this->_addCreateBlobOptionalHeaders($options, $headers);
1682
        
1683
        $this->addOptionalHeader(
1684
            $headers,
1685
            Resources::X_MS_BLOB_TYPE,
1686
            BlobType::BLOCK_BLOB
1687
        );
1688
1689
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
1690
1691
        return $this->sendAsync(
1692
            $method,
1693
            $headers,
1694
            $queryParams,
1695
            $postParams,
1696
            $path,
1697
            Resources::STATUS_CREATED,
1698
            $content,
1699
            $options
1700
        )->then(
1701
            function ($response) {
1702
                return PutBlobResult::create(
1703
                    HttpFormatter::formatHeaders($response->getHeaders())
1704
                );
1705
            },
1706
            null
1707
        );
1708
    }
1709
1710
    /**
1711
     * This method creates the blob blocks. This method will send the request
1712
     * concurrently for better performance.
1713
     *
1714
     * @param  string                   $container  Name of the container
1715
     * @param  string                   $blob       Name of the blob
1716
     * @param  StreamInterface          $content    Content's stream
1717
     * @param  Models\CreateBlobOptions $options    Array that contains
1718
     *                                                     all the option
1719
     *
1720
     * @return \GuzzleHttp\Promise\PromiseInterface
1721
     */
1722
    protected function createBlockBlobByMultipleUploadAsync(
1723
        $container,
1724
        $blob,
1725
        $content,
1726
        Models\CreateBlobOptions $options = null
1727
    ) {
1728
        Validate::isString($container, 'container');
1729
        Validate::isString($blob, 'blob');
1730
1731
        if (is_null($options)) {
1732
            $options = new CreateBlobOptions();
1733
        }
1734
1735
        $createBlobBlockOptions = CreateBlobBlockOptions::create($options);
1736
        $selfInstance = $this;
1737
1738
        $method      = Resources::HTTP_PUT;
1739
        $headers     = $this->createBlobBlockHeader($createBlobBlockOptions);
1740
        $postParams  = array();
1741
        $path        = $this->_createPath($container, $blob);
1742
1743
        $blockIds = array();
1744
        // if threshold is lower than 4mb, honor threshold, else use 4mb
1745
        $blockSize = (
1746
            $this->_SingleBlobUploadThresholdInBytes
1747
                < Resources::MB_IN_BYTES_4) ?
1748
            $this->_SingleBlobUploadThresholdInBytes : Resources::MB_IN_BYTES_4;
1749
        $counter = 0;
1750
        //create the generator for requests.
1751
        //this generator also constructs the blockId array on the fly.
1752
        $generator = function () use (
1753
            $content,
1754
            &$blockIds,
1755
            $blockSize,
1756
            $createBlobBlockOptions,
1757
            $method,
1758
            $headers,
1759
            $postParams,
1760
            $path,
1761
            &$counter,
1762
            $selfInstance
1763
        ) {
1764
            //read the content.
1765
            $blockContent = $content->read($blockSize);
1766
            //construct the blockId
1767
            $blockId = base64_encode(
1768
                str_pad($counter++, 6, '0', STR_PAD_LEFT)
1769
            );
1770
            $size = strlen($blockContent);
1771
            if ($size == 0) {
1772
                return null;
1773
            }
1774
            //add the id to array.
1775
            array_push($blockIds, new Block($blockId, 'Uncommitted'));
1776
            $queryParams = $selfInstance->createBlobBlockQueryParams(
1777
                $createBlobBlockOptions,
1778
                $blockId,
1779
                true
1780
            );
1781
            //return the array of requests.
1782
            return $selfInstance->createRequest(
1783
                $method,
1784
                $headers,
1785
                $queryParams,
1786
                $postParams,
1787
                $path,
1788
                LocationMode::PRIMARY_ONLY,
1789
                $blockContent
1790
            );
1791
        };
1792
1793
        //Send the request concurrently.
1794
        //Does not need to evaluate the results. If operation not successful,
1795
        //exception will be thrown.
1796
        $putBlobPromise = $this->sendConcurrentAsync(
1797
            $generator,
1798
            Resources::STATUS_CREATED,
1799
            $options
1800
        );
1801
1802
        $commitBlobPromise = $putBlobPromise->then(
1803
            function ($value) use (
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1803
            function (/** @scrutinizer ignore-unused */ $value) use (

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1804
                $selfInstance,
1805
                $container,
1806
                $blob,
1807
                &$blockIds,
1808
                $putBlobPromise,
0 ignored issues
show
Unused Code introduced by
The import $putBlobPromise is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
1809
                $options
1810
            ) {
1811
                return $selfInstance->commitBlobBlocksAsync(
1812
                    $container,
1813
                    $blob,
1814
                    $blockIds,
1815
                    CommitBlobBlocksOptions::create($options)
1816
                );
1817
            },
1818
            null
1819
        );
1820
1821
        return $commitBlobPromise;
1822
    }
1823
1824
1825
    /**
1826
     * This method upload the page blob pages. This method will send the request
1827
     * concurrently for better performance.
1828
     *
1829
     * @param  string                   $container  Name of the container
1830
     * @param  string                   $blob       Name of the blob
1831
     * @param  StreamInterface          $content    Content's stream
1832
     * @param  Models\CreateBlobOptions $options    Array that contains
1833
     *                                                     all the option
1834
     *
1835
     * @return \GuzzleHttp\Promise\PromiseInterface
1836
     */
1837
    private function uploadPageBlobAsync(
1838
        $container,
1839
        $blob,
1840
        $content,
1841
        Models\CreateBlobOptions $options = null
1842
    ) {
1843
        Validate::isString($container, 'container');
1844
        Validate::notNullOrEmpty($container, 'container');
1845
1846
        Validate::isString($blob, 'blob');
1847
        Validate::notNullOrEmpty($blob, 'blob');
1848
1849
        if (is_null($options)) {
1850
            $options = new CreateBlobOptions();
1851
        }
1852
        
1853
        $method      = Resources::HTTP_PUT;
1854
        $postParams  = array();
1855
        $queryParams = array();
1856
        $path        = $this->_createPath($container, $blob);
1857
1858
        $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'page');
1859
        $this->addOptionalQueryParam(
1860
            $queryParams,
1861
            Resources::QP_TIMEOUT,
1862
            $options->getTimeout()
1863
        );
1864
1865
        $pageSize = Resources::MB_IN_BYTES_4;
1866
        $start = 0;
1867
        $end = -1;
1868
1869
        //create the generator for requests.
1870
        $generator = function () use (
1871
            $content,
1872
            $pageSize,
1873
            $method,
1874
            $postParams,
1875
            $queryParams,
1876
            $path,
1877
            &$start,
1878
            &$end,
1879
            $options
1880
        ) {
1881
            //read the content.
1882
            $pageContent;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $pageContent seems to be never defined.
Loading history...
1883
            $size;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $size seems to be never defined.
Loading history...
1884
            
1885
            do {
1886
                $pageContent = $content->read($pageSize);
1887
                $size = strlen($pageContent);
1888
1889
                if ($size == 0) {
1890
                    return null;
1891
                }
1892
                
1893
                $end += $size;
1894
                $start = ($end - $size + 1);
1895
                
1896
                // If all Zero, skip this range
1897
            } while (Utilities::allZero($pageContent));
1898
1899
            $headers = array();
1900
            $headers = $this->_addOptionalRangeHeader(
1901
                $headers,
1902
                $start,
1903
                $end
1904
            );
1905
            $headers = $this->addOptionalAccessConditionHeader(
1906
                $headers,
1907
                $options->getAccessConditions()
1908
            );
1909
            $this->addOptionalHeader(
1910
                $headers,
1911
                Resources::X_MS_LEASE_ID,
1912
                $options->getLeaseId()
1913
            );
1914
            $this->addOptionalHeader(
1915
                $headers,
1916
                Resources::X_MS_PAGE_WRITE,
1917
                PageWriteOption::UPDATE_OPTION
1918
            );
1919
1920
            //return the array of requests.
1921
            return $this->createRequest(
1922
                $method,
1923
                $headers,
1924
                $queryParams,
1925
                $postParams,
1926
                $path,
1927
                LocationMode::PRIMARY_ONLY,
1928
                $pageContent
1929
            );
1930
        };
1931
1932
        //Send the request concurrently.
1933
        //Does not need to evaluate the results. If operation is not successful,
1934
        //exception will be thrown.
1935
        return $this->sendConcurrentAsync(
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->sendConcur...s->getRequestOptions()) returns the type array which is incompatible with the documented return type GuzzleHttp\Promise\PromiseInterface.
Loading history...
1936
            $generator,
1937
            Resources::STATUS_CREATED,
1938
            $options->getRequestOptions()
0 ignored issues
show
Bug introduced by
The method getRequestOptions() does not exist on MicrosoftAzure\Storage\B...odels\CreateBlobOptions. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1938
            $options->/** @scrutinizer ignore-call */ 
1939
                      getRequestOptions()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1939
        );
1940
    }
1941
    
1942
    /**
1943
     * Clears a range of pages from the blob.
1944
     *
1945
     * @param string                        $container name of the container
1946
     * @param string                        $blob      name of the blob
1947
     * @param Range                         $range     Can be up to the value of
1948
     *                                                 the blob's full size.
1949
     *                                                 Note that ranges must be
1950
     *                                                 aligned to 512 (0-511,
1951
     *                                                 512-1023)
1952
     * @param Models\CreateBlobPagesOptions $options   optional parameters
1953
     *
1954
     * @return Models\CreateBlobPagesResult
1955
     *
1956
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
1957
     */
1958
    public function clearBlobPages(
1959
        $container,
1960
        $blob,
1961
        Range $range,
1962
        Models\CreateBlobPagesOptions $options = null
1963
    ) {
1964
        return $this->clearBlobPagesAsync(
1965
            $container,
1966
            $blob,
1967
            $range,
1968
            $options
1969
        )->wait();
1970
    }
1971
1972
    /**
1973
     * Creates promise to clear a range of pages from the blob.
1974
     *
1975
     * @param string                        $container name of the container
1976
     * @param string                        $blob      name of the blob
1977
     * @param Range                         $range     Can be up to the value of
1978
     *                                                 the blob's full size.
1979
     *                                                 Note that ranges must be
1980
     *                                                 aligned to 512 (0-511,
1981
     *                                                 512-1023)
1982
     * @param Models\CreateBlobPagesOptions $options   optional parameters
1983
     *
1984
     * @return \GuzzleHttp\Promise\PromiseInterface
1985
     *
1986
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
1987
     */
1988
    public function clearBlobPagesAsync(
1989
        $container,
1990
        $blob,
1991
        Range $range,
1992
        Models\CreateBlobPagesOptions $options = null
1993
    ) {
1994
        return $this->_updatePageBlobPagesAsyncImpl(
1995
            PageWriteOption::CLEAR_OPTION,
1996
            $container,
1997
            $blob,
1998
            $range,
1999
            Resources::EMPTY_STRING,
2000
            $options
2001
        );
2002
    }
2003
    
2004
    /**
2005
     * Creates a range of pages to a page blob.
2006
     *
2007
     * @param string                          $container name of the container
2008
     * @param string                          $blob      name of the blob
2009
     * @param Range                           $range     Can be up to 4 MB in
2010
     *                                                   size. Note that ranges
2011
     *                                                   must be aligned to 512
2012
     *                                                   (0-511, 512-1023)
2013
     * @param string|resource|StreamInterface $content   the blob contents.
2014
     * @param Models\CreateBlobPagesOptions   $options   optional parameters
2015
     *
2016
     * @return Models\CreateBlobPagesResult
2017
     *
2018
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
2019
     */
2020
    public function createBlobPages(
2021
        $container,
2022
        $blob,
2023
        Range $range,
2024
        $content,
2025
        Models\CreateBlobPagesOptions $options = null
2026
    ) {
2027
        return $this->createBlobPagesAsync(
2028
            $container,
2029
            $blob,
2030
            $range,
2031
            $content,
2032
            $options
2033
        )->wait();
2034
    }
2035
2036
    /**
2037
     * Creates promise to create a range of pages to a page blob.
2038
     *
2039
     * @param string                          $container name of the container
2040
     * @param string                          $blob      name of the blob
2041
     * @param Range                           $range     Can be up to 4 MB in
2042
     *                                                   size. Note that ranges
2043
     *                                                   must be aligned to 512
2044
     *                                                   (0-511, 512-1023)
2045
     * @param string|resource|StreamInterface $content   the blob contents.
2046
     * @param Models\CreateBlobPagesOptions   $options   optional parameters
2047
     *
2048
     * @return \GuzzleHttp\Promise\PromiseInterface
2049
     *
2050
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
2051
     */
2052
    public function createBlobPagesAsync(
2053
        $container,
2054
        $blob,
2055
        Range $range,
2056
        $content,
2057
        Models\CreateBlobPagesOptions $options = null
2058
    ) {
2059
        $contentStream = Psr7\stream_for($content);
0 ignored issues
show
Bug introduced by
The function stream_for was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2059
        $contentStream = /** @scrutinizer ignore-call */ Psr7\stream_for($content);
Loading history...
2060
        //because the content is at most 4MB long, can retrieve all the data
2061
        //here at once.
2062
        $body = $contentStream->getContents();
2063
2064
        //if the range is not align to 512, throw exception.
2065
        $chunks = (int)($range->getLength() / 512);
2066
        if ($chunks * 512 != $range->getLength()) {
2067
            throw new \RuntimeException(Resources::ERROR_RANGE_NOT_ALIGN_TO_512);
2068
        }
2069
2070
        return $this->_updatePageBlobPagesAsyncImpl(
2071
            PageWriteOption::UPDATE_OPTION,
2072
            $container,
2073
            $blob,
2074
            $range,
2075
            $body,
2076
            $options
2077
        );
2078
    }
2079
    
2080
    /**
2081
     * Creates a new block to be committed as part of a block blob.
2082
     *
2083
     * @param string                          $container name of the container
2084
     * @param string                          $blob      name of the blob
2085
     * @param string                          $blockId   must be less than or
2086
     *                                                   equal to 64 bytes in
2087
     *                                                   size. For a given blob,
2088
     *                                                   the length of the value
2089
     *                                                   specified for the
2090
     *                                                   blockid parameter must
2091
     *                                                   be the same size for
2092
     *                                                   each block.
2093
     * @param resource|string|StreamInterface $content   the blob block contents
2094
     * @param Models\CreateBlobBlockOptions   $options   optional parameters
2095
     *
2096
     * @return Models\PutBlockResult
2097
     *
2098
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx
2099
     */
2100
    public function createBlobBlock(
2101
        $container,
2102
        $blob,
2103
        $blockId,
2104
        $content,
2105
        Models\CreateBlobBlockOptions $options = null
2106
    ) {
2107
        return $this->createBlobBlockAsync(
2108
            $container,
2109
            $blob,
2110
            $blockId,
2111
            $content,
2112
            $options
2113
        )->wait();
2114
    }
2115
2116
    /**
2117
     * Creates a new block to be committed as part of a block blob.
2118
     *
2119
     * @param string                          $container name of the container
2120
     * @param string                          $blob      name of the blob
2121
     * @param string                          $blockId   must be less than or
2122
     *                                                   equal to 64 bytes in
2123
     *                                                   size. For a given blob,
2124
     *                                                   the length of the value
2125
     *                                                   specified for the
2126
     *                                                   blockid parameter must
2127
     *                                                   be the same size for
2128
     *                                                   each block.
2129
     * @param resource|string|StreamInterface $content   the blob block contents
2130
     * @param Models\CreateBlobBlockOptions   $options   optional parameters
2131
     *
2132
     * @return \GuzzleHttp\Promise\PromiseInterface
2133
     *
2134
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx
2135
     */
2136
    public function createBlobBlockAsync(
2137
        $container,
2138
        $blob,
2139
        $blockId,
2140
        $content,
2141
        Models\CreateBlobBlockOptions $options = null
2142
    ) {
2143
        Validate::isString($container, 'container');
2144
        Validate::isString($blob, 'blob');
2145
        Validate::notNullOrEmpty($blob, 'blob');
2146
        Validate::isString($blockId, 'blockId');
2147
        Validate::notNullOrEmpty($blockId, 'blockId');
2148
2149
        if (is_null($options)) {
2150
            $options = new CreateBlobBlockOptions();
2151
        }
2152
        
2153
        $method         = Resources::HTTP_PUT;
2154
        $headers        = $this->createBlobBlockHeader($options);
2155
        $postParams     = array();
2156
        $queryParams    = $this->createBlobBlockQueryParams($options, $blockId);
2157
        $path           = $this->_createPath($container, $blob);
2158
        $statusCode     = Resources::STATUS_CREATED;
0 ignored issues
show
Unused Code introduced by
The assignment to $statusCode is dead and can be removed.
Loading history...
2159
        $contentStream  = Psr7\stream_for($content);
0 ignored issues
show
Bug introduced by
The function stream_for was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2159
        $contentStream  = /** @scrutinizer ignore-call */ Psr7\stream_for($content);
Loading history...
2160
        $body           = $contentStream->getContents();
2161
        
2162
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
2163
2164
        return $this->sendAsync(
2165
            $method,
2166
            $headers,
2167
            $queryParams,
2168
            $postParams,
2169
            $path,
2170
            Resources::STATUS_CREATED,
2171
            $body,
2172
            $options
2173
        )->then(function ($response) {
2174
            return PutBlockResult::create(
2175
                HttpFormatter::formatHeaders($response->getHeaders())
2176
            );
2177
        });
2178
    }
2179
    
2180
    /**
2181
     * Commits a new block of data to the end of an existing append blob.
2182
     *
2183
     * @param string                          $container name of the container
2184
     * @param string                          $blob      name of the blob
2185
     * @param resource|string|StreamInterface $content   the blob block contents
2186
     * @param Models\AppendBlockOptions       $options   optional parameters
2187
     *
2188
     * @return Models\AppendBlockResult
2189
     *
2190
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/append-block
2191
     */
2192
    public function appendBlock(
2193
        $container,
2194
        $blob,
2195
        $content,
2196
        Models\AppendBlockOptions $options = null
2197
    ) {
2198
        return $this->appendBlockAsync(
2199
            $container,
2200
            $blob,
2201
            $content,
2202
            $options
2203
        )->wait();
2204
    }
2205
2206
2207
    /**
2208
     * Creates promise to commit a new block of data to the end of an existing append blob.
2209
     *
2210
     * @param string                          $container name of the container
2211
     * @param string                          $blob      name of the blob
2212
     * @param resource|string|StreamInterface $content   the blob block contents
2213
     * @param Models\AppendBlockOptions       $options   optional parameters
2214
     *
2215
     * @return \GuzzleHttp\Promise\PromiseInterface
2216
     *
2217
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/append-block
2218
     */
2219
    public function appendBlockAsync(
2220
        $container,
2221
        $blob,
2222
        $content,
2223
        Models\AppendBlockOptions $options = null
2224
    ) {
2225
        Validate::isString($container, 'container');
2226
        Validate::notNullOrEmpty($container, 'container');
2227
        Validate::isString($blob, 'blob');
2228
        Validate::notNullOrEmpty($blob, 'blob');
2229
2230
        if (is_null($options)) {
2231
            $options = new AppendBlockOptions();
2232
        }
2233
        
2234
        $method         = Resources::HTTP_PUT;
2235
        $headers        = array();
2236
        $postParams     = array();
2237
        $queryParams    = array();
2238
        $path           = $this->_createPath($container, $blob);
2239
        $statusCode     = Resources::STATUS_CREATED;
0 ignored issues
show
Unused Code introduced by
The assignment to $statusCode is dead and can be removed.
Loading history...
2240
2241
        $contentStream  = Psr7\stream_for($content);
0 ignored issues
show
Bug introduced by
The function stream_for was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2241
        $contentStream  = /** @scrutinizer ignore-call */ Psr7\stream_for($content);
Loading history...
2242
        $length         = $contentStream->getSize();
2243
        $body           = $contentStream->getContents();
2244
2245
        $this->addOptionalQueryParam(
2246
            $queryParams,
2247
            Resources::QP_COMP,
2248
            'appendblock'
2249
        );
2250
        
2251
        $headers  = $this->addOptionalAccessConditionHeader(
2252
            $headers,
2253
            $options->getAccessConditions()
2254
        );
2255
2256
        $this->addOptionalHeader(
2257
            $headers,
2258
            Resources::CONTENT_LENGTH,
2259
            $length
2260
        );
2261
        $this->addOptionalHeader(
2262
            $headers,
2263
            Resources::CONTENT_MD5,
2264
            $options->getContentMD5()
2265
        );
2266
        $this->addOptionalHeader(
2267
            $headers,
2268
            Resources::X_MS_BLOB_CONDITION_MAXSIZE,
2269
            $options->getMaxBlobSize()
2270
        );
2271
        $this->addOptionalHeader(
2272
            $headers,
2273
            Resources::X_MS_BLOB_CONDITION_APPENDPOS,
2274
            $options->getAppendPosition()
2275
        );
2276
        $this->addOptionalHeader(
2277
            $headers,
2278
            Resources::X_MS_LEASE_ID,
2279
            $options->getLeaseId()
2280
        );
2281
        
2282
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
2283
2284
        return $this->sendAsync(
2285
            $method,
2286
            $headers,
2287
            $queryParams,
2288
            $postParams,
2289
            $path,
2290
            Resources::STATUS_CREATED,
2291
            $body,
2292
            $options
2293
        )->then(function ($response) {
2294
            return AppendBlockResult::create(
2295
                HttpFormatter::formatHeaders($response->getHeaders())
2296
            );
2297
        });
2298
    }
2299
2300
    /**
2301
     * create the header for createBlobBlock(s)
2302
     * @param  Models\CreateBlobBlockOptions $options the option of the request
2303
     *
2304
     * @return array
2305
     */
2306
    protected function createBlobBlockHeader(Models\CreateBlobBlockOptions $options = null)
2307
    {
2308
        $headers = array();
2309
        $this->addOptionalHeader(
2310
            $headers,
2311
            Resources::X_MS_LEASE_ID,
2312
            $options->getLeaseId()
2313
        );
2314
        $this->addOptionalHeader(
2315
            $headers,
2316
            Resources::CONTENT_MD5,
2317
            $options->getContentMD5()
2318
        );
2319
        $this->addOptionalHeader(
2320
            $headers,
2321
            Resources::CONTENT_TYPE,
2322
            Resources::URL_ENCODED_CONTENT_TYPE
2323
        );
2324
2325
        return $headers;
2326
    }
2327
2328
    /**
2329
     * create the query params for createBlobBlock(s)
2330
     * @param  Models\CreateBlobBlockOptions $options      the option of the
2331
     *                                                     request
2332
     * @param  string                        $blockId      the block id of the
2333
     *                                                     block.
2334
     * @param  bool                          $isConcurrent if the query
2335
     *                                                     parameter is for
2336
     *                                                     concurrent upload.
2337
     *
2338
     * @return array  the constructed query parameters.
2339
     */
2340
    protected function createBlobBlockQueryParams(
2341
        Models\CreateBlobBlockOptions $options,
2342
        $blockId,
2343
        $isConcurrent = false
2344
    ) {
2345
        $queryParams = array();
2346
        $this->addOptionalQueryParam(
2347
            $queryParams,
2348
            Resources::QP_COMP,
2349
            'block'
2350
        );
2351
        $this->addOptionalQueryParam(
2352
            $queryParams,
2353
            Resources::QP_BLOCKID,
2354
            $blockId
2355
        );
2356
        if ($isConcurrent) {
2357
            $this->addOptionalQueryParam(
2358
                $queryParams,
2359
                Resources::QP_TIMEOUT,
2360
                $options->getTimeout()
2361
            );
2362
        }
2363
        
2364
        return $queryParams;
2365
    }
2366
2367
    /**
2368
     * This method writes a blob by specifying the list of block IDs that make up the
2369
     * blob. In order to be written as part of a blob, a block must have been
2370
     * successfully written to the server in a prior createBlobBlock method.
2371
     *
2372
     * You can call Put Block List to update a blob by uploading only those blocks
2373
     * that have changed, then committing the new and existing blocks together.
2374
     * You can do this by specifying whether to commit a block from the committed
2375
     * block list or from the uncommitted block list, or to commit the most recently
2376
     * uploaded version of the block, whichever list it may belong to.
2377
     *
2378
     * @param string                         $container The container name.
2379
     * @param string                         $blob      The blob name.
2380
     * @param Models\BlockList|array         $blockList The block entries.
2381
     * @param Models\CommitBlobBlocksOptions $options   The optional parameters.
2382
     *
2383
     * @return Models\PutBlobResult
2384
     *
2385
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx
2386
     */
2387
    public function commitBlobBlocks(
2388
        $container,
2389
        $blob,
2390
        $blockList,
2391
        Models\CommitBlobBlocksOptions $options = null
2392
    ) {
2393
        return $this->commitBlobBlocksAsync(
2394
            $container,
2395
            $blob,
2396
            $blockList,
2397
            $options
2398
        )->wait();
2399
    }
2400
2401
    /**
2402
     * This method writes a blob by specifying the list of block IDs that make up the
2403
     * blob. In order to be written as part of a blob, a block must have been
2404
     * successfully written to the server in a prior createBlobBlock method.
2405
     *
2406
     * You can call Put Block List to update a blob by uploading only those blocks
2407
     * that have changed, then committing the new and existing blocks together.
2408
     * You can do this by specifying whether to commit a block from the committed
2409
     * block list or from the uncommitted block list, or to commit the most recently
2410
     * uploaded version of the block, whichever list it may belong to.
2411
     *
2412
     * @param string                         $container The container name.
2413
     * @param string                         $blob      The blob name.
2414
     * @param Models\BlockList|array         $blockList The block entries.
2415
     * @param Models\CommitBlobBlocksOptions $options   The optional parameters.
2416
     *
2417
     * @return \GuzzleHttp\Promise\PromiseInterface
2418
     *
2419
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx
2420
     */
2421
    public function commitBlobBlocksAsync(
2422
        $container,
2423
        $blob,
2424
        $blockList,
2425
        Models\CommitBlobBlocksOptions $options = null
2426
    ) {
2427
        Validate::isString($container, 'container');
2428
        Validate::isString($blob, 'blob');
2429
        Validate::notNullOrEmpty($blob, 'blob');
2430
        Validate::isTrue(
2431
            $blockList instanceof BlockList || is_array($blockList),
2432
            sprintf(
2433
                Resources::INVALID_PARAM_MSG,
2434
                'blockList',
2435
                get_class(new BlockList())
2436
            )
2437
        );
2438
        
2439
        $method      = Resources::HTTP_PUT;
2440
        $headers     = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $headers is dead and can be removed.
Loading history...
2441
        $postParams  = array();
2442
        $queryParams = array();
2443
        $path        = $this->_createPath($container, $blob);
2444
        $isArray     = is_array($blockList);
2445
        $blockList   = $isArray ? BlockList::create($blockList) : $blockList;
2446
        $body        = $blockList->toXml($this->dataSerializer);
2447
        
2448
        if (is_null($options)) {
2449
            $options = new CommitBlobBlocksOptions();
2450
        }
2451
        
2452
        $blobContentType            = $options->getContentType();
2453
        $blobContentEncoding        = $options->getContentEncoding();
2454
        $blobContentLanguage        = $options->getContentLanguage();
2455
        $blobContentMD5             = $options->getContentMD5();
2456
        $blobCacheControl           = $options->getCacheControl();
2457
        $blobCcontentDisposition    = $options->getContentDisposition();
2458
        $leaseId                    = $options->getLeaseId();
2459
        $contentType                = Resources::URL_ENCODED_CONTENT_TYPE;
2460
        
2461
        $metadata = $options->getMetadata();
2462
        $headers  = $this->generateMetadataHeaders($metadata);
2463
        $headers  = $this->addOptionalAccessConditionHeader(
2464
            $headers,
2465
            $options->getAccessConditions()
2466
        );
2467
        
2468
        $this->addOptionalHeader(
2469
            $headers,
2470
            Resources::X_MS_LEASE_ID,
2471
            $leaseId
2472
        );
2473
        $this->addOptionalHeader(
2474
            $headers,
2475
            Resources::X_MS_BLOB_CACHE_CONTROL,
2476
            $blobCacheControl
2477
        );
2478
        $this->addOptionalHeader(
2479
            $headers,
2480
            Resources::X_MS_BLOB_CONTENT_DISPOSITION,
2481
            $blobCcontentDisposition
2482
        );
2483
        $this->addOptionalHeader(
2484
            $headers,
2485
            Resources::X_MS_BLOB_CONTENT_TYPE,
2486
            $blobContentType
2487
        );
2488
        $this->addOptionalHeader(
2489
            $headers,
2490
            Resources::X_MS_BLOB_CONTENT_ENCODING,
2491
            $blobContentEncoding
2492
        );
2493
        $this->addOptionalHeader(
2494
            $headers,
2495
            Resources::X_MS_BLOB_CONTENT_LANGUAGE,
2496
            $blobContentLanguage
2497
        );
2498
        $this->addOptionalHeader(
2499
            $headers,
2500
            Resources::X_MS_BLOB_CONTENT_MD5,
2501
            $blobContentMD5
2502
        );
2503
        $this->addOptionalHeader(
2504
            $headers,
2505
            Resources::CONTENT_TYPE,
2506
            $contentType
2507
        );
2508
        
2509
        $this->addOptionalQueryParam(
2510
            $queryParams,
2511
            Resources::QP_COMP,
2512
            'blocklist'
2513
        );
2514
        
2515
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
2516
2517
        return $this->sendAsync(
2518
            $method,
2519
            $headers,
2520
            $queryParams,
2521
            $postParams,
2522
            $path,
2523
            Resources::STATUS_CREATED,
2524
            $body,
2525
            $options
2526
        )->then(function ($response) {
2527
            return PutBlobResult::create(
2528
                HttpFormatter::formatHeaders($response->getHeaders())
2529
            );
2530
        }, null);
2531
    }
2532
    
2533
    /**
2534
     * Retrieves the list of blocks that have been uploaded as part of a block blob.
2535
     *
2536
     * There are two block lists maintained for a blob:
2537
     * 1) Committed Block List: The list of blocks that have been successfully
2538
     *    committed to a given blob with commitBlobBlocks.
2539
     * 2) Uncommitted Block List: The list of blocks that have been uploaded for a
2540
     *    blob using Put Block (REST API), but that have not yet been committed.
2541
     *    These blocks are stored in Windows Azure in association with a blob, but do
2542
     *    not yet form part of the blob.
2543
     *
2544
     * @param string                       $container name of the container
2545
     * @param string                       $blob      name of the blob
2546
     * @param Models\ListBlobBlocksOptions $options   optional parameters
2547
     *
2548
     * @return Models\ListBlobBlocksResult
2549
     *
2550
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179400.aspx
2551
     */
2552
    public function listBlobBlocks(
2553
        $container,
2554
        $blob,
2555
        Models\ListBlobBlocksOptions $options = null
2556
    ) {
2557
        return $this->listBlobBlocksAsync($container, $blob, $options)->wait();
2558
    }
2559
2560
    /**
2561
     * Creates promise to retrieve the list of blocks that have been uploaded as
2562
     * part of a block blob.
2563
     *
2564
     * There are two block lists maintained for a blob:
2565
     * 1) Committed Block List: The list of blocks that have been successfully
2566
     *    committed to a given blob with commitBlobBlocks.
2567
     * 2) Uncommitted Block List: The list of blocks that have been uploaded for a
2568
     *    blob using Put Block (REST API), but that have not yet been committed.
2569
     *    These blocks are stored in Windows Azure in association with a blob, but do
2570
     *    not yet form part of the blob.
2571
     *
2572
     * @param string                       $container name of the container
2573
     * @param string                       $blob      name of the blob
2574
     * @param Models\ListBlobBlocksOptions $options   optional parameters
2575
     *
2576
     * @return \GuzzleHttp\Promise\PromiseInterface
2577
     *
2578
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179400.aspx
2579
     */
2580
    public function listBlobBlocksAsync(
2581
        $container,
2582
        $blob,
2583
        Models\ListBlobBlocksOptions $options = null
2584
    ) {
2585
        Validate::isString($container, 'container');
2586
        Validate::isString($blob, 'blob');
2587
        Validate::notNullOrEmpty($blob, 'blob');
2588
        
2589
        $method      = Resources::HTTP_GET;
2590
        $headers     = array();
2591
        $postParams  = array();
2592
        $queryParams = array();
2593
        $path        = $this->_createPath($container, $blob);
2594
        
2595
        if (is_null($options)) {
2596
            $options = new ListBlobBlocksOptions();
2597
        }
2598
        
2599
        $this->addOptionalHeader(
2600
            $headers,
2601
            Resources::X_MS_LEASE_ID,
2602
            $options->getLeaseId()
2603
        );
2604
        
2605
        $this->addOptionalQueryParam(
2606
            $queryParams,
2607
            Resources::QP_BLOCK_LIST_TYPE,
2608
            $options->getBlockListType()
2609
        );
2610
        $this->addOptionalQueryParam(
2611
            $queryParams,
2612
            Resources::QP_SNAPSHOT,
2613
            $options->getSnapshot()
2614
        );
2615
        $this->addOptionalQueryParam(
2616
            $queryParams,
2617
            Resources::QP_COMP,
2618
            'blocklist'
2619
        );
2620
        
2621
        return $this->sendAsync(
2622
            $method,
2623
            $headers,
2624
            $queryParams,
2625
            $postParams,
2626
            $path,
2627
            Resources::STATUS_OK,
2628
            Resources::EMPTY_STRING,
2629
            $options
2630
        )->then(function ($response) {
2631
            $parsed = $this->dataSerializer->unserialize($response->getBody());
2632
        
2633
            return ListBlobBlocksResult::create(
2634
                HttpFormatter::formatHeaders($response->getHeaders()),
2635
                $parsed
2636
            );
2637
        }, null);
2638
    }
2639
    
2640
    /**
2641
     * Returns all properties and metadata on the blob.
2642
     *
2643
     * @param string                          $container name of the container
2644
     * @param string                          $blob      name of the blob
2645
     * @param Models\GetBlobPropertiesOptions $options   optional parameters
2646
     *
2647
     * @return Models\GetBlobPropertiesResult
2648
     *
2649
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179394.aspx
2650
     */
2651
    public function getBlobProperties(
2652
        $container,
2653
        $blob,
2654
        Models\GetBlobPropertiesOptions $options = null
2655
    ) {
2656
        return $this->getBlobPropertiesAsync(
2657
            $container,
2658
            $blob,
2659
            $options
2660
        )->wait();
2661
    }
2662
    
2663
    /**
2664
     * Creates promise to return all properties and metadata on the blob.
2665
     *
2666
     * @param string                          $container name of the container
2667
     * @param string                          $blob      name of the blob
2668
     * @param Models\GetBlobPropertiesOptions $options   optional parameters
2669
     *
2670
     * @return \GuzzleHttp\Promise\PromiseInterface
2671
     *
2672
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179394.aspx
2673
     */
2674
    public function getBlobPropertiesAsync(
2675
        $container,
2676
        $blob,
2677
        Models\GetBlobPropertiesOptions $options = null
2678
    ) {
2679
        Validate::isString($container, 'container');
2680
        Validate::isString($blob, 'blob');
2681
        Validate::notNullOrEmpty($blob, 'blob');
2682
        
2683
        $method      = Resources::HTTP_HEAD;
2684
        $headers     = array();
2685
        $postParams  = array();
2686
        $queryParams = array();
2687
        $path        = $this->_createPath($container, $blob);
2688
        
2689
        if (is_null($options)) {
2690
            $options = new GetBlobPropertiesOptions();
2691
        }
2692
        
2693
        $headers = $this->addOptionalAccessConditionHeader(
2694
            $headers,
2695
            $options->getAccessConditions()
2696
        );
2697
        
2698
        $this->addOptionalHeader(
2699
            $headers,
2700
            Resources::X_MS_LEASE_ID,
2701
            $options->getLeaseId()
2702
        );
2703
        $this->addOptionalQueryParam(
2704
            $queryParams,
2705
            Resources::QP_SNAPSHOT,
2706
            $options->getSnapshot()
2707
        );
2708
        
2709
        return $this->sendAsync(
2710
            $method,
2711
            $headers,
2712
            $queryParams,
2713
            $postParams,
2714
            $path,
2715
            Resources::STATUS_OK,
2716
            Resources::EMPTY_STRING,
2717
            $options
2718
        )->then(function ($response) {
2719
            $formattedHeaders = HttpFormatter::formatHeaders($response->getHeaders());
2720
            return GetBlobPropertiesResult::create($formattedHeaders);
2721
        }, null);
2722
    }
2723
2724
    /**
2725
     * Returns all properties and metadata on the blob.
2726
     *
2727
     * @param string                        $container name of the container
2728
     * @param string                        $blob      name of the blob
2729
     * @param Models\GetBlobMetadataOptions $options   optional parameters
2730
     *
2731
     * @return Models\GetBlobMetadataResult
2732
     *
2733
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179350.aspx
2734
     */
2735
    public function getBlobMetadata(
2736
        $container,
2737
        $blob,
2738
        Models\GetBlobMetadataOptions $options = null
2739
    ) {
2740
        return $this->getBlobMetadataAsync($container, $blob, $options)->wait();
2741
    }
2742
2743
    /**
2744
     * Creates promise to return all properties and metadata on the blob.
2745
     *
2746
     * @param string                        $container name of the container
2747
     * @param string                        $blob      name of the blob
2748
     * @param Models\GetBlobMetadataOptions $options   optional parameters
2749
     *
2750
     * @return \GuzzleHttp\Promise\PromiseInterface
2751
     *
2752
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179350.aspx
2753
     */
2754
    public function getBlobMetadataAsync(
2755
        $container,
2756
        $blob,
2757
        Models\GetBlobMetadataOptions $options = null
2758
    ) {
2759
        Validate::isString($container, 'container');
2760
        Validate::isString($blob, 'blob');
2761
        Validate::notNullOrEmpty($blob, 'blob');
2762
        
2763
        $method      = Resources::HTTP_HEAD;
2764
        $headers     = array();
2765
        $postParams  = array();
2766
        $queryParams = array();
2767
        $path        = $this->_createPath($container, $blob);
2768
        
2769
        if (is_null($options)) {
2770
            $options = new GetBlobMetadataOptions();
2771
        }
2772
        
2773
        $headers = $this->addOptionalAccessConditionHeader(
2774
            $headers,
2775
            $options->getAccessConditions()
2776
        );
2777
        
2778
        $this->addOptionalHeader(
2779
            $headers,
2780
            Resources::X_MS_LEASE_ID,
2781
            $options->getLeaseId()
2782
        );
2783
        $this->addOptionalQueryParam(
2784
            $queryParams,
2785
            Resources::QP_SNAPSHOT,
2786
            $options->getSnapshot()
2787
        );
2788
2789
        $this->addOptionalQueryParam(
2790
            $queryParams,
2791
            Resources::QP_COMP,
2792
            'metadata'
2793
        );
2794
        
2795
        return $this->sendAsync(
2796
            $method,
2797
            $headers,
2798
            $queryParams,
2799
            $postParams,
2800
            $path,
2801
            Resources::STATUS_OK,
2802
            Resources::EMPTY_STRING,
2803
            $options
2804
        )->then(function ($response) {
2805
            $responseHeaders = HttpFormatter::formatHeaders($response->getHeaders());
2806
            return GetBlobMetadataResult::create($responseHeaders);
2807
        });
2808
    }
2809
    
2810
    /**
2811
     * Returns a list of active page ranges for a page blob. Active page ranges are
2812
     * those that have been populated with data.
2813
     *
2814
     * @param string                           $container name of the container
2815
     * @param string                           $blob      name of the blob
2816
     * @param Models\ListPageBlobRangesOptions $options   optional parameters
2817
     *
2818
     * @return Models\ListPageBlobRangesResult
2819
     *
2820
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691973.aspx
2821
     */
2822
    public function listPageBlobRanges(
2823
        $container,
2824
        $blob,
2825
        Models\ListPageBlobRangesOptions $options = null
2826
    ) {
2827
        return $this->listPageBlobRangesAsync(
2828
            $container,
2829
            $blob,
2830
            $options
2831
        )->wait();
2832
    }
2833
2834
    /**
2835
     * Creates promise to return a list of active page ranges for a page blob.
2836
     * Active page ranges are those that have been populated with data.
2837
     *
2838
     * @param string                           $container name of the container
2839
     * @param string                           $blob      name of the blob
2840
     * @param Models\ListPageBlobRangesOptions $options   optional parameters
2841
     *
2842
     * @return \GuzzleHttp\Promise\PromiseInterface
2843
     *
2844
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691973.aspx
2845
     */
2846
    public function listPageBlobRangesAsync(
2847
        $container,
2848
        $blob,
2849
        Models\ListPageBlobRangesOptions $options = null
2850
    ) {
2851
        Validate::isString($container, 'container');
2852
        Validate::isString($blob, 'blob');
2853
        Validate::notNullOrEmpty($blob, 'blob');
2854
        
2855
        $method      = Resources::HTTP_GET;
2856
        $headers     = array();
2857
        $queryParams = array();
2858
        $postParams  = array();
2859
        $path        = $this->_createPath($container, $blob);
2860
        
2861
        if (is_null($options)) {
2862
            $options = new ListPageBlobRangesOptions();
2863
        }
2864
        
2865
        $headers = $this->addOptionalAccessConditionHeader(
2866
            $headers,
2867
            $options->getAccessConditions()
2868
        );
2869
        
2870
        $headers = $this->_addOptionalRangeHeader(
2871
            $headers,
2872
            $options->getRangeStart(),
2873
            $options->getRangeEnd()
2874
        );
2875
        
2876
        $this->addOptionalHeader(
2877
            $headers,
2878
            Resources::X_MS_LEASE_ID,
2879
            $options->getLeaseId()
2880
        );
2881
        $this->addOptionalQueryParam(
2882
            $queryParams,
2883
            Resources::QP_SNAPSHOT,
2884
            $options->getSnapshot()
2885
        );
2886
        $this->addOptionalQueryParam(
2887
            $queryParams,
2888
            Resources::QP_COMP,
2889
            'pagelist'
2890
        );
2891
        
2892
        $dataSerializer = $this->dataSerializer;
2893
2894
        return $this->sendAsync(
2895
            $method,
2896
            $headers,
2897
            $queryParams,
2898
            $postParams,
2899
            $path,
2900
            Resources::STATUS_OK,
2901
            Resources::EMPTY_STRING,
2902
            $options
2903
        )->then(function ($response) use ($dataSerializer) {
2904
            $parsed = $dataSerializer->unserialize($response->getBody());
2905
            return ListPageBlobRangesResult::create(
2906
                HttpFormatter::formatHeaders($response->getHeaders()),
2907
                $parsed
2908
            );
2909
        }, null);
2910
    }
2911
    
2912
    /**
2913
     * Sets system properties defined for a blob.
2914
     *
2915
     * @param string                          $container name of the container
2916
     * @param string                          $blob      name of the blob
2917
     * @param Models\SetBlobPropertiesOptions $options   optional parameters
2918
     *
2919
     * @return Models\SetBlobPropertiesResult
2920
     *
2921
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691966.aspx
2922
     */
2923
    public function setBlobProperties(
2924
        $container,
2925
        $blob,
2926
        Models\SetBlobPropertiesOptions $options = null
2927
    ) {
2928
        return $this->setBlobPropertiesAsync(
2929
            $container,
2930
            $blob,
2931
            $options
2932
        )->wait();
2933
    }
2934
2935
    /**
2936
     * Creates promise to set system properties defined for a blob.
2937
     *
2938
     * @param string                          $container name of the container
2939
     * @param string                          $blob      name of the blob
2940
     * @param Models\SetBlobPropertiesOptions $options   optional parameters
2941
     *
2942
     * @return \GuzzleHttp\Promise\PromiseInterface
2943
     *
2944
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691966.aspx
2945
     */
2946
    public function setBlobPropertiesAsync(
2947
        $container,
2948
        $blob,
2949
        Models\SetBlobPropertiesOptions $options = null
2950
    ) {
2951
        Validate::isString($container, 'container');
2952
        Validate::isString($blob, 'blob');
2953
        Validate::notNullOrEmpty($blob, 'blob');
2954
        
2955
        $method      = Resources::HTTP_PUT;
2956
        $headers     = array();
2957
        $postParams  = array();
2958
        $queryParams = array();
2959
        $path        = $this->_createPath($container, $blob);
2960
        
2961
        if (is_null($options)) {
2962
            $options = new SetBlobPropertiesOptions();
2963
        }
2964
        
2965
        $blobContentType            = $options->getContentType();
2966
        $blobContentEncoding        = $options->getContentEncoding();
2967
        $blobContentLanguage        = $options->getContentLanguage();
2968
        $blobContentLength          = $options->getContentLength();
2969
        $blobContentMD5             = $options->getContentMD5();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $blobContentMD5 is correct as $options->getContentMD5() targeting MicrosoftAzure\Storage\B...ptions::getContentMD5() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
2970
        $blobCacheControl           = $options->getCacheControl();
2971
        $blobContentDisposition    = $options->getContentDisposition();
2972
        $leaseId             = $options->getLeaseId();
2973
        $sNumberAction       = $options->getSequenceNumberAction();
2974
        $sNumber             = $options->getSequenceNumber();
2975
        
2976
        $headers = $this->addOptionalAccessConditionHeader(
2977
            $headers,
2978
            $options->getAccessConditions()
2979
        );
2980
        
2981
        $this->addOptionalHeader(
2982
            $headers,
2983
            Resources::X_MS_LEASE_ID,
2984
            $leaseId
2985
        );
2986
        $this->addOptionalHeader(
2987
            $headers,
2988
            Resources::X_MS_BLOB_CACHE_CONTROL,
2989
            $blobCacheControl
2990
        );
2991
        $this->addOptionalHeader(
2992
            $headers,
2993
            Resources::X_MS_BLOB_CONTENT_DISPOSITION,
2994
            $blobContentDisposition
2995
        );
2996
        $this->addOptionalHeader(
2997
            $headers,
2998
            Resources::X_MS_BLOB_CONTENT_TYPE,
2999
            $blobContentType
3000
        );
3001
        $this->addOptionalHeader(
3002
            $headers,
3003
            Resources::X_MS_BLOB_CONTENT_ENCODING,
3004
            $blobContentEncoding
3005
        );
3006
        $this->addOptionalHeader(
3007
            $headers,
3008
            Resources::X_MS_BLOB_CONTENT_LANGUAGE,
3009
            $blobContentLanguage
3010
        );
3011
        $this->addOptionalHeader(
3012
            $headers,
3013
            Resources::X_MS_BLOB_CONTENT_LENGTH,
3014
            $blobContentLength
3015
        );
3016
        $this->addOptionalHeader(
3017
            $headers,
3018
            Resources::X_MS_BLOB_CONTENT_MD5,
3019
            $blobContentMD5
0 ignored issues
show
Bug introduced by
$blobContentMD5 of type void is incompatible with the type string expected by parameter $value of MicrosoftAzure\Storage\C...xy::addOptionalHeader(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3019
            /** @scrutinizer ignore-type */ $blobContentMD5
Loading history...
3020
        );
3021
        $this->addOptionalHeader(
3022
            $headers,
3023
            Resources::X_MS_BLOB_SEQUENCE_NUMBER_ACTION,
3024
            $sNumberAction
3025
        );
3026
        $this->addOptionalHeader(
3027
            $headers,
3028
            Resources::X_MS_BLOB_SEQUENCE_NUMBER,
3029
            $sNumber
3030
        );
3031
3032
        $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'properties');
3033
        
3034
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
3035
3036
        return $this->sendAsync(
3037
            $method,
3038
            $headers,
3039
            $queryParams,
3040
            $postParams,
3041
            $path,
3042
            Resources::STATUS_OK,
3043
            Resources::EMPTY_STRING,
3044
            $options
3045
        )->then(function ($response) {
3046
            return SetBlobPropertiesResult::create(
3047
                HttpFormatter::formatHeaders($response->getHeaders())
3048
            );
3049
        }, null);
3050
    }
3051
    
3052
    /**
3053
     * Sets metadata headers on the blob.
3054
     *
3055
     * @param string                        $container name of the container
3056
     * @param string                        $blob      name of the blob
3057
     * @param array                         $metadata  key/value pair representation
3058
     * @param Models\BlobServiceOptions     $options   optional parameters
3059
     *
3060
     * @return Models\SetBlobMetadataResult
3061
     *
3062
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179414.aspx
3063
     */
3064
    public function setBlobMetadata(
3065
        $container,
3066
        $blob,
3067
        array $metadata,
3068
        Models\BlobServiceOptions $options = null
3069
    ) {
3070
        return $this->setBlobMetadataAsync(
3071
            $container,
3072
            $blob,
3073
            $metadata,
3074
            $options
3075
        )->wait();
3076
    }
3077
3078
    /**
3079
     * Creates promise to set metadata headers on the blob.
3080
     *
3081
     * @param string                        $container name of the container
3082
     * @param string                        $blob      name of the blob
3083
     * @param array                         $metadata  key/value pair representation
3084
     * @param Models\BlobServiceOptions     $options   optional parameters
3085
     *
3086
     * @return \GuzzleHttp\Promise\PromiseInterface
3087
     *
3088
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179414.aspx
3089
     */
3090
    public function setBlobMetadataAsync(
3091
        $container,
3092
        $blob,
3093
        array $metadata,
3094
        Models\BlobServiceOptions $options = null
3095
    ) {
3096
        Validate::isString($container, 'container');
3097
        Validate::isString($blob, 'blob');
3098
        Validate::notNullOrEmpty($blob, 'blob');
3099
        Utilities::validateMetadata($metadata);
3100
        
3101
        $method      = Resources::HTTP_PUT;
3102
        $headers     = array();
3103
        $postParams  = array();
3104
        $queryParams = array();
3105
        $path        = $this->_createPath($container, $blob);
3106
        
3107
        if (is_null($options)) {
3108
            $options = new BlobServiceOptions();
3109
        }
3110
        
3111
        $headers = $this->addOptionalAccessConditionHeader(
3112
            $headers,
3113
            $options->getAccessConditions()
3114
        );
3115
        $headers = $this->addMetadataHeaders($headers, $metadata);
3116
        
3117
        $this->addOptionalHeader(
3118
            $headers,
3119
            Resources::X_MS_LEASE_ID,
3120
            $options->getLeaseId()
3121
        );
3122
        $this->addOptionalQueryParam(
3123
            $queryParams,
3124
            Resources::QP_COMP,
3125
            'metadata'
3126
        );
3127
        
3128
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
3129
3130
        return $this->sendAsync(
3131
            $method,
3132
            $headers,
3133
            $queryParams,
3134
            $postParams,
3135
            $path,
3136
            Resources::STATUS_OK,
3137
            Resources::EMPTY_STRING,
3138
            $options
3139
        )->then(function ($response) {
3140
            return SetBlobMetadataResult::create(
3141
                HttpFormatter::formatHeaders($response->getHeaders())
3142
            );
3143
        }, null);
3144
    }
3145
3146
    /**
3147
     * Downloads a blob to a file, the result contains its metadata and
3148
     * properties. The result will not contain a stream pointing to the
3149
     * content of the file.
3150
     *
3151
     * @param string                $path      The path and name of the file
3152
     * @param string                $container name of the container
3153
     * @param string                $blob      name of the blob
3154
     * @param Models\GetBlobOptions $options   optional parameters
3155
     *
3156
     * @return Models\GetBlobResult
3157
     *
3158
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx
3159
     */
3160
    public function saveBlobToFile(
3161
        $path,
3162
        $container,
3163
        $blob,
3164
        Models\GetBlobOptions $options = null
3165
    ) {
3166
        return $this->saveBlobToFileAsync(
3167
            $path,
3168
            $container,
3169
            $blob,
3170
            $options
3171
        )->wait();
3172
    }
3173
3174
    /**
3175
     * Creates promise to download a blob to a file, the result contains its
3176
     * metadata and properties. The result will not contain a stream pointing
3177
     * to the content of the file.
3178
     *
3179
     * @param string                $path      The path and name of the file
3180
     * @param string                $container name of the container
3181
     * @param string                $blob      name of the blob
3182
     * @param Models\GetBlobOptions $options   optional parameters
3183
     *
3184
     * @return \GuzzleHttp\Promise\PromiseInterface
3185
     *
3186
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx
3187
     */
3188
    public function saveBlobToFileAsync(
3189
        $path,
3190
        $container,
3191
        $blob,
3192
        Models\GetBlobOptions $options = null
3193
    ) {
3194
        $resource = fopen($path, 'w+');
3195
        if ($resource == null) {
3196
            throw new \Exception(Resources::ERROR_FILE_COULD_NOT_BE_OPENED);
3197
        }
3198
        return $this->getBlobAsync($container, $blob, $options)->then(
3199
            function ($result) use ($path, $resource) {
0 ignored issues
show
Unused Code introduced by
The import $path is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
3200
                $content = $result->getContentStream();
3201
                while (!feof($content)) {
3202
                    fwrite(
3203
                        $resource,
3204
                        stream_get_contents($content, Resources::MB_IN_BYTES_4)
3205
                    );
3206
                }
3207
                
3208
                $content = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $content is dead and can be removed.
Loading history...
3209
                fclose($resource);
3210
        
3211
                return $result;
3212
            },
3213
            null
3214
        );
3215
    }
3216
    
3217
    /**
3218
     * Reads or downloads a blob from the system, including its metadata and
3219
     * properties.
3220
     *
3221
     * @param string                $container name of the container
3222
     * @param string                $blob      name of the blob
3223
     * @param Models\GetBlobOptions $options   optional parameters
3224
     *
3225
     * @return Models\GetBlobResult
3226
     *
3227
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx
3228
     */
3229
    public function getBlob(
3230
        $container,
3231
        $blob,
3232
        Models\GetBlobOptions $options = null
3233
    ) {
3234
        return $this->getBlobAsync($container, $blob, $options)->wait();
3235
    }
3236
3237
    /**
3238
     * Creates promise to read or download a blob from the system, including its
3239
     * metadata and properties.
3240
     *
3241
     * @param string                $container name of the container
3242
     * @param string                $blob      name of the blob
3243
     * @param Models\GetBlobOptions $options   optional parameters
3244
     *
3245
     * @return \GuzzleHttp\Promise\PromiseInterface
3246
     *
3247
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx
3248
     */
3249
    public function getBlobAsync(
3250
        $container,
3251
        $blob,
3252
        Models\GetBlobOptions $options = null
3253
    ) {
3254
        Validate::isString($container, 'container');
3255
        Validate::isString($blob, 'blob');
3256
        
3257
        $method      = Resources::HTTP_GET;
3258
        $headers     = array();
3259
        $postParams  = array();
3260
        $queryParams = array();
3261
        $path        = $this->_createPath($container, $blob);
3262
        
3263
        if (is_null($options)) {
3264
            $options = new GetBlobOptions();
3265
        }
3266
        
3267
        $getMD5  = $options->getComputeRangeMD5();
3268
        $headers = $this->addOptionalAccessConditionHeader(
3269
            $headers,
3270
            $options->getAccessConditions()
3271
        );
3272
        $headers = $this->_addOptionalRangeHeader(
3273
            $headers,
3274
            $options->getRangeStart(),
3275
            $options->getRangeEnd()
3276
        );
3277
        
3278
        $this->addOptionalHeader(
3279
            $headers,
3280
            Resources::X_MS_LEASE_ID,
3281
            $options->getLeaseId()
3282
        );
3283
        $this->addOptionalHeader(
3284
            $headers,
3285
            Resources::X_MS_RANGE_GET_CONTENT_MD5,
3286
            $getMD5 ? 'true' : null
3287
        );
3288
        $this->addOptionalQueryParam(
3289
            $queryParams,
3290
            Resources::QP_SNAPSHOT,
3291
            $options->getSnapshot()
3292
        );
3293
3294
        $options->setIsStreaming(true);
3295
        
3296
        return $this->sendAsync(
3297
            $method,
3298
            $headers,
3299
            $queryParams,
3300
            $postParams,
3301
            $path,
3302
            array(Resources::STATUS_OK, Resources::STATUS_PARTIAL_CONTENT),
3303
            Resources::EMPTY_STRING,
3304
            $options
3305
        )->then(function ($response) {
3306
            $metadata = Utilities::getMetadataArray(
3307
                HttpFormatter::formatHeaders($response->getHeaders())
3308
            );
3309
        
3310
            return GetBlobResult::create(
3311
                HttpFormatter::formatHeaders($response->getHeaders()),
3312
                $response->getBody(),
3313
                $metadata
3314
            );
3315
        });
3316
    }
3317
    
3318
    /**
3319
     * Deletes a blob or blob snapshot.
3320
     *
3321
     * Note that if the snapshot entry is specified in the $options then only this
3322
     * blob snapshot is deleted. To delete all blob snapshots, do not set Snapshot
3323
     * and just set getDeleteSnaphotsOnly to true.
3324
     *
3325
     * @param string                   $container name of the container
3326
     * @param string                   $blob      name of the blob
3327
     * @param Models\DeleteBlobOptions $options   optional parameters
3328
     *
3329
     * @return void
3330
     *
3331
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179413.aspx
3332
     */
3333
    public function deleteBlob(
3334
        $container,
3335
        $blob,
3336
        Models\DeleteBlobOptions $options = null
3337
    ) {
3338
        $this->deleteBlobAsync($container, $blob, $options)->wait();
3339
    }
3340
3341
    /**
3342
     * Creates promise to delete a blob or blob snapshot.
3343
     *
3344
     * Note that if the snapshot entry is specified in the $options then only this
3345
     * blob snapshot is deleted. To delete all blob snapshots, do not set Snapshot
3346
     * and just set getDeleteSnaphotsOnly to true.
3347
     *
3348
     * @param string                   $container name of the container
3349
     * @param string                   $blob      name of the blob
3350
     * @param Models\DeleteBlobOptions $options   optional parameters
3351
     *
3352
     * @return \GuzzleHttp\Promise\PromiseInterface
3353
     *
3354
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179413.aspx
3355
     */
3356
    public function deleteBlobAsync(
3357
        $container,
3358
        $blob,
3359
        Models\DeleteBlobOptions $options = null
3360
    ) {
3361
        Validate::isString($container, 'container');
3362
        Validate::isString($blob, 'blob');
3363
        Validate::notNullOrEmpty($blob, 'blob');
3364
        
3365
        $method      = Resources::HTTP_DELETE;
3366
        $headers     = array();
3367
        $postParams  = array();
3368
        $queryParams = array();
3369
        $path        = $this->_createPath($container, $blob);
3370
        
3371
        if (is_null($options)) {
3372
            $options = new DeleteBlobOptions();
3373
        }
3374
        
3375
        if (is_null($options->getSnapshot())) {
0 ignored issues
show
introduced by
The condition is_null($options->getSnapshot()) is always false.
Loading history...
3376
            $delSnapshots = $options->getDeleteSnaphotsOnly() ? 'only' : 'include';
3377
            $this->addOptionalHeader(
3378
                $headers,
3379
                Resources::X_MS_DELETE_SNAPSHOTS,
3380
                $delSnapshots
3381
            );
3382
        } else {
3383
            $this->addOptionalQueryParam(
3384
                $queryParams,
3385
                Resources::QP_SNAPSHOT,
3386
                $options->getSnapshot()
3387
            );
3388
        }
3389
        
3390
        $headers = $this->addOptionalAccessConditionHeader(
3391
            $headers,
3392
            $options->getAccessConditions()
3393
        );
3394
        
3395
        $this->addOptionalHeader(
3396
            $headers,
3397
            Resources::X_MS_LEASE_ID,
3398
            $options->getLeaseId()
3399
        );
3400
        
3401
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
3402
3403
        return $this->sendAsync(
3404
            $method,
3405
            $headers,
3406
            $queryParams,
3407
            $postParams,
3408
            $path,
3409
            Resources::STATUS_ACCEPTED,
3410
            Resources::EMPTY_STRING,
3411
            $options
3412
        );
3413
    }
3414
    
3415
    /**
3416
     * Creates a snapshot of a blob.
3417
     *
3418
     * @param string                           $container The name of the container.
3419
     * @param string                           $blob      The name of the blob.
3420
     * @param Models\CreateBlobSnapshotOptions $options   The optional parameters.
3421
     *
3422
     * @return Models\CreateBlobSnapshotResult
3423
     *
3424
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691971.aspx
3425
     */
3426
    public function createBlobSnapshot(
3427
        $container,
3428
        $blob,
3429
        Models\CreateBlobSnapshotOptions $options = null
3430
    ) {
3431
        return $this->createBlobSnapshotAsync(
3432
            $container,
3433
            $blob,
3434
            $options
3435
        )->wait();
3436
    }
3437
3438
    /**
3439
     * Creates promise to create a snapshot of a blob.
3440
     *
3441
     * @param string                           $container The name of the container.
3442
     * @param string                           $blob      The name of the blob.
3443
     * @param Models\CreateBlobSnapshotOptions $options   The optional parameters.
3444
     *
3445
     * @return \GuzzleHttp\Promise\PromiseInterface
3446
     *
3447
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691971.aspx
3448
     */
3449
    public function createBlobSnapshotAsync(
3450
        $container,
3451
        $blob,
3452
        Models\CreateBlobSnapshotOptions $options = null
3453
    ) {
3454
        Validate::isString($container, 'container');
3455
        Validate::isString($blob, 'blob');
3456
        Validate::notNullOrEmpty($blob, 'blob');
3457
        
3458
        $method             = Resources::HTTP_PUT;
3459
        $headers            = array();
3460
        $postParams         = array();
3461
        $queryParams        = array();
3462
        $path               = $this->_createPath($container, $blob);
3463
        
3464
        if (is_null($options)) {
3465
            $options = new CreateBlobSnapshotOptions();
3466
        }
3467
        
3468
        $queryParams[Resources::QP_COMP] = 'snapshot';
3469
3470
        $headers = $this->addOptionalAccessConditionHeader(
3471
            $headers,
3472
            $options->getAccessConditions()
3473
        );
3474
        $headers = $this->addMetadataHeaders($headers, $options->getMetadata());
3475
        $this->addOptionalHeader(
3476
            $headers,
3477
            Resources::X_MS_LEASE_ID,
3478
            $options->getLeaseId()
3479
        );
3480
        
3481
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
3482
3483
        return $this->sendAsync(
3484
            $method,
3485
            $headers,
3486
            $queryParams,
3487
            $postParams,
3488
            $path,
3489
            Resources::STATUS_CREATED,
3490
            Resources::EMPTY_STRING,
3491
            $options
3492
        )->then(function ($response) {
3493
            return CreateBlobSnapshotResult::create(
3494
                HttpFormatter::formatHeaders($response->getHeaders())
3495
            );
3496
        }, null);
3497
    }
3498
    
3499
    /**
3500
     * Copies a source blob to a destination blob within the same storage account.
3501
     *
3502
     * @param string                 $destinationContainer name of the destination
3503
     * container
3504
     * @param string                 $destinationBlob      name of the destination
3505
     * blob
3506
     * @param string                 $sourceContainer      name of the source
3507
     * container
3508
     * @param string                 $sourceBlob           name of the source
3509
     * blob
3510
     * @param Models\CopyBlobOptions $options              optional parameters
3511
     *
3512
     * @return Models\CopyBlobResult
3513
     *
3514
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd894037.aspx
3515
     */
3516
    public function copyBlob(
3517
        $destinationContainer,
3518
        $destinationBlob,
3519
        $sourceContainer,
3520
        $sourceBlob,
3521
        Models\CopyBlobOptions $options = null
3522
    ) {
3523
        return $this->copyBlobAsync(
3524
            $destinationContainer,
3525
            $destinationBlob,
3526
            $sourceContainer,
3527
            $sourceBlob,
3528
            $options
3529
        )->wait();
3530
    }
3531
3532
    /**
3533
     * Creates promise to copy a source blob to a destination blob within the
3534
     * same storage account.
3535
     *
3536
     * @param string                 $destinationContainer name of the destination
3537
     * container
3538
     * @param string                 $destinationBlob      name of the destination
3539
     * blob
3540
     * @param string                 $sourceContainer      name of the source
3541
     * container
3542
     * @param string                 $sourceBlob           name of the source
3543
     * blob
3544
     * @param Models\CopyBlobOptions $options              optional parameters
3545
     *
3546
     * @return \GuzzleHttp\Promise\PromiseInterface
3547
     *
3548
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd894037.aspx
3549
     */
3550
    public function copyBlobAsync(
3551
        $destinationContainer,
3552
        $destinationBlob,
3553
        $sourceContainer,
3554
        $sourceBlob,
3555
        Models\CopyBlobOptions $options = null
3556
    ) {
3557
        $method              = Resources::HTTP_PUT;
3558
        $headers             = array();
3559
        $postParams          = array();
3560
        $queryParams         = array();
3561
        $destinationBlobPath = $this->_createPath(
3562
            $destinationContainer,
3563
            $destinationBlob
3564
        );
3565
        
3566
        if (is_null($options)) {
3567
            $options = new CopyBlobOptions();
3568
        }
3569
        
3570
        $sourceBlobPath = $this->_getCopyBlobSourceName(
3571
            $sourceContainer,
3572
            $sourceBlob,
3573
            $options
3574
        );
3575
        
3576
        $headers = $this->addOptionalAccessConditionHeader(
3577
            $headers,
3578
            $options->getAccessConditions()
3579
        );
3580
        
3581
        $headers = $this->addOptionalSourceAccessConditionHeader(
3582
            $headers,
3583
            $options->getSourceAccessConditions()
3584
        );
3585
        
3586
        $this->addOptionalHeader(
3587
            $headers,
3588
            Resources::X_MS_COPY_SOURCE,
3589
            $sourceBlobPath
3590
        );
3591
        
3592
        $headers = $this->addMetadataHeaders($headers, $options->getMetadata());
3593
        
3594
        $this->addOptionalHeader(
3595
            $headers,
3596
            Resources::X_MS_LEASE_ID,
3597
            $options->getLeaseId()
3598
        );
3599
        
3600
        $this->addOptionalHeader(
3601
            $headers,
3602
            Resources::X_MS_SOURCE_LEASE_ID,
3603
            $options->getSourceLeaseId()
3604
        );
3605
        
3606
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
3607
        
3608
        return $this->sendAsync(
3609
            $method,
3610
            $headers,
3611
            $queryParams,
3612
            $postParams,
3613
            $destinationBlobPath,
3614
            Resources::STATUS_ACCEPTED,
3615
            Resources::EMPTY_STRING,
3616
            $options
3617
        )->then(function ($response) {
3618
            return CopyBlobResult::create(
3619
                HttpFormatter::formatHeaders($response->getHeaders())
3620
            );
3621
        }, null);
3622
    }
3623
    
3624
    /**
3625
     * Abort a blob copy operation
3626
     *
3627
     * @param string                        $container            name of the container
3628
     * @param string                        $blob                 name of the blob
3629
     * @param string                        $copyId               copy operation identifier.
3630
     * @param Models\BlobServiceOptions     $options              optional parameters
3631
     *
3632
     * @return void
3633
     *
3634
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/abort-copy-blob
3635
     */
3636
    public function abortCopy(
3637
        $container,
3638
        $blob,
3639
        $copyId,
3640
        Models\BlobServiceOptions $options = null
3641
    ) {
3642
        return $this->abortCopyAsync(
3643
            $container,
3644
            $blob,
3645
            $copyId,
3646
            $options
3647
        )->wait();
3648
    }
3649
3650
    /**
3651
     * Creates promise to abort a blob copy operation
3652
     *
3653
     * @param string                        $container            name of the container
3654
     * @param string                        $blob                 name of the blob
3655
     * @param string                        $copyId               copy operation identifier.
3656
     * @param Models\BlobServiceOptions     $options              optional parameters
3657
     *
3658
     * @return \GuzzleHttp\Promise\PromiseInterface
3659
     *
3660
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/abort-copy-blob
3661
     */
3662
    public function abortCopyAsync(
3663
        $container,
3664
        $blob,
3665
        $copyId,
3666
        Models\BlobServiceOptions $options = null
3667
    ) {
3668
        Validate::isString($container, 'container');
3669
        Validate::isString($blob, 'blob');
3670
        Validate::isString($copyId, 'copyId');
3671
        Validate::notNullOrEmpty($container, 'container');
3672
        Validate::notNullOrEmpty($blob, 'blob');
3673
        Validate::notNullOrEmpty($copyId, 'copyId');
3674
        
3675
        $method              = Resources::HTTP_PUT;
3676
        $headers             = array();
3677
        $postParams          = array();
3678
        $queryParams         = array();
3679
        $destinationBlobPath = $this->_createPath(
3680
            $container,
3681
            $blob
3682
        );
3683
        
3684
        if (is_null($options)) {
3685
            $options = new BlobServiceOptions();
3686
        }
3687
        
3688
        $this->addOptionalQueryParam(
3689
            $queryParams,
3690
            Resources::QP_TIMEOUT,
3691
            $options->getTimeout()
3692
        );
3693
3694
        $this->addOptionalQueryParam(
3695
            $queryParams,
3696
            Resources::QP_COMP,
3697
            'copy'
3698
        );
3699
3700
        $this->addOptionalQueryParam(
3701
            $queryParams,
3702
            Resources::QP_COPY_ID,
3703
            $copyId
3704
        );
3705
        
3706
        $this->addOptionalHeader(
3707
            $headers,
3708
            Resources::X_MS_LEASE_ID,
3709
            $options->getLeaseId()
3710
        );
3711
        
3712
        $this->addOptionalHeader(
3713
            $headers,
3714
            Resources::X_MS_COPY_ACTION,
3715
            'abort'
3716
        );
3717
        
3718
        return $this->sendAsync(
3719
            $method,
3720
            $headers,
3721
            $queryParams,
3722
            $postParams,
3723
            $destinationBlobPath,
3724
            Resources::STATUS_NO_CONTENT,
3725
            Resources::EMPTY_STRING,
3726
            $options
3727
        );
3728
    }
3729
        
3730
    /**
3731
     * Establishes an exclusive write lock on a blob. To write to a locked
3732
     * blob, a client must provide a lease ID.
3733
     *
3734
     * @param string                     $container         name of the container
3735
     * @param string                     $blob              name of the blob
3736
     * @param string                     $proposedLeaseId   lease id when acquiring
3737
     * @param int                        $leaseDuration     the lease duration. A non-infinite
3738
     *                                                      lease can be between 15 and 60 seconds.
3739
     *                                                      Default is never to expire.
3740
     * @param Models\BlobServiceOptions  $options           optional parameters
3741
     *
3742
     * @return Models\LeaseResult
3743
     *
3744
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx
3745
     */
3746
    public function acquireLease(
3747
        $container,
3748
        $blob,
3749
        $proposedLeaseId = null,
3750
        $leaseDuration = null,
3751
        Models\BlobServiceOptions $options = null
3752
    ) {
3753
        return $this->acquireLeaseAsync(
3754
            $container,
3755
            $blob,
3756
            $proposedLeaseId,
3757
            $leaseDuration,
3758
            $options
3759
        )->wait();
3760
    }
3761
3762
    /**
3763
     * Creates promise to establish an exclusive one-minute write lock on a blob.
3764
     * To write to a locked blob, a client must provide a lease ID.
3765
     *
3766
     * @param string                     $container         name of the container
3767
     * @param string                     $blob              name of the blob
3768
     * @param string                     $proposedLeaseId   lease id when acquiring
3769
     * @param int                        $leaseDuration     the lease duration. A non-infinite
3770
     *                                                      lease can be between 15 and 60 seconds.
3771
     *                                                      Default is never to expire.
3772
     * @param Models\BlobServiceOptions  $options           optional parameters
3773
     *
3774
     * @return \GuzzleHttp\Promise\PromiseInterface
3775
     *
3776
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx
3777
     */
3778
    public function acquireLeaseAsync(
3779
        $container,
3780
        $blob,
3781
        $proposedLeaseId = null,
3782
        $leaseDuration = null,
3783
        Models\BlobServiceOptions $options = null
3784
    ) {
3785
        if ($options === null) {
3786
            $options = new BlobServiceOptions();
3787
        }
3788
3789
        if ($leaseDuration === null) {
3790
            $leaseDuration = -1;
3791
        }
3792
3793
        return $this->_putLeaseAsyncImpl(
3794
            LeaseMode::ACQUIRE_ACTION,
3795
            $container,
3796
            $blob,
3797
            $proposedLeaseId,
3798
            $leaseDuration,
3799
            null /* leaseId */,
3800
            null /* breakPeriod */,
3801
            self::getStatusCodeOfLeaseAction(LeaseMode::ACQUIRE_ACTION),
3802
            $options,
3803
            $options->getAccessConditions()
0 ignored issues
show
Bug introduced by
$options->getAccessConditions() of type MicrosoftAzure\Storage\B...odels\AccessCondition[] is incompatible with the type MicrosoftAzure\Storage\B...ls\AccessCondition|null expected by parameter $accessCondition of MicrosoftAzure\Storage\B...y::_putLeaseAsyncImpl(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

3803
            /** @scrutinizer ignore-type */ $options->getAccessConditions()
Loading history...
3804
        )->then(function ($response) {
3805
            return LeaseResult::create(
3806
                HttpFormatter::formatHeaders($response->getHeaders())
3807
            );
3808
        }, null);
3809
    }
3810
    
3811
    /**
3812
     * change an existing lease
3813
     *
3814
     * @param string                    $container         name of the container
3815
     * @param string                    $blob              name of the blob
3816
     * @param string                    $leaseId           lease id when acquiring
3817
     * @param string                    $proposedLeaseId   lease id when acquiring
3818
     * @param Models\BlobServiceOptions $options           optional parameters
3819
     *
3820
     * @return Models\LeaseResult
3821
     *
3822
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3823
     */
3824
    public function changeLease(
3825
        $container,
3826
        $blob,
3827
        $leaseId,
3828
        $proposedLeaseId,
3829
        Models\BlobServiceOptions $options = null
3830
    ) {
3831
        return $this->changeLeaseAsync(
3832
            $container,
3833
            $blob,
3834
            $leaseId,
3835
            $proposedLeaseId,
3836
            $options
3837
        )->wait();
3838
    }
3839
3840
    /**
3841
     * Creates promise to change an existing lease
3842
     *
3843
     * @param string                    $container         name of the container
3844
     * @param string                    $blob              name of the blob
3845
     * @param string                    $leaseId           lease id when acquiring
3846
     * @param string                    $proposedLeaseId   the proposed lease id
3847
     * @param Models\BlobServiceOptions $options           optional parameters
3848
     *
3849
     * @return \GuzzleHttp\Promise\PromiseInterface
3850
     *
3851
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3852
     */
3853
    public function changeLeaseAsync(
3854
        $container,
3855
        $blob,
3856
        $leaseId,
3857
        $proposedLeaseId,
3858
        Models\BlobServiceOptions $options = null
3859
    ) {
3860
        return $this->_putLeaseAsyncImpl(
3861
            LeaseMode::CHANGE_ACTION,
3862
            $container,
3863
            $blob,
3864
            $proposedLeaseId,
3865
            null /* leaseDuration */,
3866
            $leaseId,
3867
            null /* breakPeriod */,
3868
            self::getStatusCodeOfLeaseAction(LeaseMode::RENEW_ACTION),
3869
            is_null($options) ? new BlobServiceOptions() : $options
3870
        )->then(function ($response) {
3871
            return LeaseResult::create(
3872
                HttpFormatter::formatHeaders($response->getHeaders())
3873
            );
3874
        }, null);
3875
    }
3876
    
3877
    /**
3878
     * Renews an existing lease
3879
     *
3880
     * @param string                    $container name of the container
3881
     * @param string                    $blob      name of the blob
3882
     * @param string                    $leaseId   lease id when acquiring
3883
     * @param Models\BlobServiceOptions $options   optional parameters
3884
     *
3885
     * @return Models\LeaseResult
3886
     *
3887
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3888
     */
3889
    public function renewLease(
3890
        $container,
3891
        $blob,
3892
        $leaseId,
3893
        Models\BlobServiceOptions $options = null
3894
    ) {
3895
        return $this->renewLeaseAsync(
3896
            $container,
3897
            $blob,
3898
            $leaseId,
3899
            $options
3900
        )->wait();
3901
    }
3902
3903
    /**
3904
     * Creates promise to renew an existing lease
3905
     *
3906
     * @param string                    $container name of the container
3907
     * @param string                    $blob      name of the blob
3908
     * @param string                    $leaseId   lease id when acquiring
3909
     * @param Models\BlobServiceOptions $options   optional parameters
3910
     *
3911
     * @return \GuzzleHttp\Promise\PromiseInterface
3912
     *
3913
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3914
     */
3915
    public function renewLeaseAsync(
3916
        $container,
3917
        $blob,
3918
        $leaseId,
3919
        Models\BlobServiceOptions $options = null
3920
    ) {
3921
        return $this->_putLeaseAsyncImpl(
3922
            LeaseMode::RENEW_ACTION,
3923
            $container,
3924
            $blob,
3925
            null /* proposedLeaseId */,
3926
            null /* leaseDuration */,
3927
            $leaseId,
3928
            null /* breakPeriod */,
3929
            self::getStatusCodeOfLeaseAction(LeaseMode::RENEW_ACTION),
3930
            is_null($options) ? new BlobServiceOptions() : $options
3931
        )->then(function ($response) {
3932
            return LeaseResult::create(
3933
                HttpFormatter::formatHeaders($response->getHeaders())
3934
            );
3935
        }, null);
3936
    }
3937
3938
    /**
3939
     * Frees the lease if it is no longer needed so that another client may
3940
     * immediately acquire a lease against the blob.
3941
     *
3942
     * @param string                    $container name of the container
3943
     * @param string                    $blob      name of the blob
3944
     * @param string                    $leaseId   lease id when acquiring
3945
     * @param Models\BlobServiceOptions $options   optional parameters
3946
     *
3947
     * @return void
3948
     *
3949
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3950
     */
3951
    public function releaseLease(
3952
        $container,
3953
        $blob,
3954
        $leaseId,
3955
        Models\BlobServiceOptions $options = null
3956
    ) {
3957
        $this->releaseLeaseAsync($container, $blob, $leaseId, $options)->wait();
3958
    }
3959
    
3960
    /**
3961
     * Creates promise to free the lease if it is no longer needed so that
3962
     * another client may immediately acquire a lease against the blob.
3963
     *
3964
     * @param string                    $container name of the container
3965
     * @param string                    $blob      name of the blob
3966
     * @param string                    $leaseId   lease id when acquiring
3967
     * @param Models\BlobServiceOptions $options   optional parameters
3968
     *
3969
     * @return \GuzzleHttp\Promise\PromiseInterface
3970
     *
3971
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3972
     */
3973
    public function releaseLeaseAsync(
3974
        $container,
3975
        $blob,
3976
        $leaseId,
3977
        Models\BlobServiceOptions $options = null
3978
    ) {
3979
        return $this->_putLeaseAsyncImpl(
3980
            LeaseMode::RELEASE_ACTION,
3981
            $container,
3982
            $blob,
3983
            null /* proposedLeaseId */,
3984
            null /* leaseDuration */,
3985
            $leaseId,
3986
            null /* breakPeriod */,
3987
            self::getStatusCodeOfLeaseAction(LeaseMode::RELEASE_ACTION),
3988
            is_null($options) ? new BlobServiceOptions() : $options
3989
        );
3990
    }
3991
    
3992
    /**
3993
     * Ends the lease but ensure that another client cannot acquire a new lease until
3994
     * the current lease period has expired.
3995
     *
3996
     * @param string                    $container     name of the container
3997
     * @param string                    $blob          name of the blob
3998
     * @param int                       $breakPeriod   the proposed duration of seconds that
3999
     *                                                 lease should continue before it it broken,
4000
     *                                                 between 0 and 60 seconds.
4001
     * @param Models\BlobServiceOptions $options   optional parameters
4002
     *
4003
     * @return BreakLeaseResult
4004
     *
4005
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
4006
     */
4007
    public function breakLease(
4008
        $container,
4009
        $blob,
4010
        $breakPeriod = null,
4011
        Models\BlobServiceOptions $options = null
4012
    ) {
4013
        return $this->breakLeaseAsync(
4014
            $container,
4015
            $blob,
4016
            $options
4017
        )->wait();
4018
    }
4019
4020
    /**
4021
     * Creates promise to end the lease but ensure that another client cannot
4022
     * acquire a new lease until the current lease period has expired.
4023
     *
4024
     * @param string                    $container name of the container
4025
     * @param string                    $blob      name of the blob
4026
     * @param Models\BlobServiceOptions $options   optional parameters
4027
     *
4028
     * @return \GuzzleHttp\Promise\PromiseInterface
4029
     *
4030
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
4031
     */
4032
    public function breakLeaseAsync(
4033
        $container,
4034
        $blob,
4035
        $breakPeriod = null,
4036
        Models\BlobServiceOptions $options = null
4037
    ) {
4038
        return $this->_putLeaseAsyncImpl(
4039
            LeaseMode::BREAK_ACTION,
4040
            $container,
4041
            $blob,
4042
            null /* proposedLeaseId */,
4043
            null /* leaseDuration */,
4044
            null /* leaseId */,
4045
            $breakPeriod,
4046
            self::getStatusCodeOfLeaseAction(LeaseMode::BREAK_ACTION),
4047
            is_null($options) ? new BlobServiceOptions() : $options
4048
        )->then(function ($response) {
4049
            return BreakLeaseResult::create(
4050
                HttpFormatter::formatHeaders($response->getHeaders())
4051
            );
4052
        }, null);
4053
    }
4054
4055
    /**
4056
     * Adds optional header to headers if set
4057
     *
4058
     * @param array                  $headers         The array of request headers.
4059
     * @param Models\AccessCondition $accessCondition The access condition object.
4060
     *
4061
     * @return array
4062
     */
4063
    public function addOptionalAccessConditionHeader(
4064
        array $headers,
4065
        array $accessConditions = null
4066
    ) {
4067
        if (!empty($accessConditions)) {
4068
            foreach ($accessConditions as $accessCondition) {
4069
                if (!is_null($accessCondition)) {
4070
                    $header = $accessCondition->getHeader();
4071
4072
                    if ($header != Resources::EMPTY_STRING) {
4073
                        $value = $accessCondition->getValue();
4074
                        if ($value instanceof \DateTime) {
4075
                            $value = gmdate(
4076
                                Resources::AZURE_DATE_FORMAT,
4077
                                $value->getTimestamp()
4078
                            );
4079
                        }
4080
                        $headers[$header] = $value;
4081
                    }
4082
                }
4083
            }
4084
        }
4085
4086
        return $headers;
4087
    }
4088
4089
    /**
4090
     * Adds optional header to headers if set
4091
     *
4092
     * @param array                  $headers         The array of request headers.
4093
     * @param array                  $accessCondition The access condition object.
4094
     *
4095
     * @return array
4096
     */
4097
    public function addOptionalSourceAccessConditionHeader(
4098
        array $headers,
4099
        array $accessConditions = null
4100
    ) {
4101
        if (!empty($accessConditions)) {
4102
            foreach ($accessConditions as $accessCondition) {
4103
                if (!is_null($accessCondition)) {
4104
                    $header     = $accessCondition->getHeader();
4105
                    $headerName = null;
4106
                    if (!empty($header)) {
4107
                        switch ($header) {
4108
                            case Resources::IF_MATCH:
4109
                                $headerName = Resources::X_MS_SOURCE_IF_MATCH;
4110
                                break;
4111
                            case Resources::IF_UNMODIFIED_SINCE:
4112
                                $headerName = Resources::X_MS_SOURCE_IF_UNMODIFIED_SINCE;
4113
                                break;
4114
                            case Resources::IF_MODIFIED_SINCE:
4115
                                $headerName = Resources::X_MS_SOURCE_IF_MODIFIED_SINCE;
4116
                                break;
4117
                            case Resources::IF_NONE_MATCH:
4118
                                $headerName = Resources::X_MS_SOURCE_IF_NONE_MATCH;
4119
                                break;
4120
                            default:
4121
                                throw new \Exception(Resources::INVALID_ACH_MSG);
4122
                                break;
4123
                        }
4124
                    }
4125
                    $value = $accessCondition->getValue();
4126
                    if ($value instanceof \DateTime) {
4127
                        $value = gmdate(
4128
                            Resources::AZURE_DATE_FORMAT,
4129
                            $value->getTimestamp()
4130
                        );
4131
                    }
4132
4133
                    $this->addOptionalHeader($headers, $headerName, $value);
4134
                }
4135
            }
4136
        }
4137
4138
        return $headers;
4139
    }
4140
}
4141